Swift Optional 이해하기

Steve Jack·2021년 7월 14일
0

Swift 문법(야곰)

목록 보기
3/9
post-thumbnail

야곰님의 강의 자료

옵셔널이란??

값이 있을 수도, 없을 수도 있음을 표현
nil이 할당 될 수 있는지 없는지 표현

옵셔널을 쓰는 이유

명시적 표현
1. nil의 가능성을 코드만으로 표현가능
2. 문서/주석 작성 시간 절약

안전한 사용
1. 전달받은 값이 옵셔널이 아니라면 nil 체크를 하지 않고 사용가능
2. 예외 상황을 최소화 하는 안전한 코딩
3. 효율적 코딩

// someOptionalParm에 nil이 할당 될 수 있다.
func someFunction(someOptionalParam: Int?) {
       // ....
}

/// someOptionalParm에 nil이 할당 될 수 없다.
func someFunction(someOptionalParam: Int) {
       // ....
}

someFunction(someOptionalParam: nil) // 가능
someFunction(someParam: nil) // 오류

옵셔널 문법과 선언

옵셔널 문법
enum + generics (열거형 + 제너릭)

옵셔널 선언

enum Optional<Wrapped>: ExpressibleByNiliteral {
         case none // optional 값이 있다.
         case some(Wrapped) // optional 값이 없다.
}

let optionalValue: Optional<Int> = nil
let optionalValue: Int? =nil

옵셔널 표현

  1. 느낌표(!)를 이용한 암시적 추출 옵셔널(Implicitly Unwrapped Optional)
// Implicitly Unwrapped Optional
var implicitlyUnwrappedOptionalValue: Int! = 100

switch implicitlyUnwrappedOptionalValue {
case .none:
    print("This Optional variable is nil")
case .some(let value):
    print("Value is \(value)")
}

// 기존 변수처럼 사용 가능
implicitlyUnwrappedOptionalValue = implicitlyUnwrappedOptionalValue + 1

// nil 할당 가능
implicitlyUnwrappedOptionalValue = nil

// 잘못된 접근으로 인한 런타임 오류 발생(optional 변수 접근)
implicitlyUnwrappedOptionalValue = implicitlyUnwrappedOptionalValue + 1
  1. 물음표(?)를 이용한 옵셔널
// Optional
var optionalValue: Int? = 100

switch optionalValue {
case .none:
    print("This Optional variable is nil")
case .some(let value):
    print("Value is \(value)")
}

// nil 할당 가능
optionalValue = nil

// 기존 변수처럼 사용불가 - 옵셔널과 일반 값은 다른 타입이므로 연산불가
optionalValue = optionalValue + 1

옵셔널 추출이란?

옵셔널에 들어있는 값을 사용하기 위해 꺼내오는 것

1) 옵셔널 바인딩
1. nil 체크 + 안전한 추출
2. 옵셔널 안에 값이 들어있는지 확인하고 값이 있으면 값을 꺼내옵니다.
3. if-let 방식 사용

func printName(_ name: String) { // name:string 타입
    print(name)
}

var myName: String? = nil

//printName(myName) // optinal타입 전달
// 전달되는 값의 타입이 다르기 때문에 컴파일 오류발생

if let name: String = myName {
    printName(name)
} else {
    print("myName == nil")
}


var yourName: String! = nil

if let name: String = yourName {
    printName(name)
} else {
    print("yourName == nil")
}

// name 상수는 if-let 구문 내에서만 사용가능합니다
// 상수 사용범위를 벗어났기 때문에 컴파일 오류 발생
//printName(name)


// ,를 사용해 한 번에 여러 옵셔널을 바인딩 할 수 있습니다
// 모든 옵셔널에 값이 있을 때만 동작합니다
myName = "yagom"
yourName = nil

if let name = myName, let friend = yourName {
    print("\(name) and \(friend)")
}
// yourName이 nil이기 때문에 실행되지 않습니다
yourName = "hana"

if let name = myName, let friend = yourName {
    print("\(name) and \(friend)")
}
// yagom and hana

2) 강체추출 : 옵셔널에 값이 들어있는지 아닌지 확인하지 않고 강제로 값을 꺼내는 방식, 만약 값이 없을경우(nil) 런타임 오류가 발생하기 때문에 추천되지 않습니다.

var myName: String? = yagom

// optional 타입 강제 추출
printName(myName!) // yagom

myName = nil
print(myName!)
// 강제추출시 값이 없으므로 런타임 오류 발생

var youName: String! = nil // 선언할때 강제추출:nill값 할당
printName(yourName)
// nil 값이 전달되기 때문에 런타임 오류발생
profile
To put up a flag.

0개의 댓글