[Swift] Optional

Lena·2020년 12월 1일

Optionals

  • 값이 있을 수도, 없을 수도 있다.
  • nil이 할당 될 수 있는지 없는지를 표현
  • ? 를 붙여서 나타낼 수 있다.

If Statements and Forced Unwrapping

if문으로 옵셔널의 nil 여부를 체크할 수 있다.
옵셔널 값이 존재함을 확신할 수 있는 경우, ! 으로 옵셔널 타입을 벗겨낼 수 있다(Forced Unwrapping).

if convertedNumber != nil {
    print("convertedNumber has an integer value of \(convertedNumber!).")
}

Optional Binding

옵셔널 바인딩을 통해 옵셔널의 값이 있는지 알아낼 수 있다.
if let 구문으로 바인딩할 수 있으며, 변수나 상수에 바인딩 된 값은 if문 안에서 사용할 수 있다.

let possibleNumber = "123"
if let actualNumber = Int(possibleNumber) {
    print("The string \"\(possibleNumber)\" has an integer value of \(actualNumber)")
} else {
    print("The string \"\(possibleNumber)\" could not be converted to an integer")
}

Implicitly Unwrapped Optionals

Sometimes it’s clear from a program’s structure that an optional will always have a value, after that value is first set. In these cases, it’s useful to remove the need to check and unwrap the optional’s value every time it’s accessed, because it can be safely assumed to have a value all of the time.

옵셔널 값이 처음 set 될 때처럼 분명하게 값이 있는 경우에는 타입 뒤에 !를 붙여서 implicitly unwrapped optionals로 정의할 수 있다.
암시적 언래핑 옵셔널은 주로 클래스의 초기화 과정에서 사용될 수 있다.
(as described in Unowned References and Implicitly Unwrapped Optional Properties)

@IBOutlet weak var tableView: UITableView!

Note
!은 ?와 유사한 Optional이지만, 암시적으로 언래핑한 값을 뜻함. 따라서 옵셔널 바인딩이 필요 없음. 처음 값이 초기화 되었을 때처럼 값이 있는 것을 확신할 수 있는 경우에 사용될 수 있다.
또, 암시적 언래핑 옵셔널 타입의 프로퍼티는 클래스의 초기화 과정에서 주로 사용(primary use)될 수 있는데, unowned reference와 관련된 설명을 참고할 것.

Optional chaining

Optional Chaining as an Alternative to Forced Unwrapping

강제 언래핑 대신 옵셔널 체이닝을 사용할 수 있다. 옵셔널 체이닝의 경우 데이터 타입은 항상 옵셔널이며(리턴되는 값에 옵셔널이 붙어서 리턴), nil을 반환할 수 있다.

Specifically, the result of an optional chaining call is of the same type as the expected return value, but wrapped in an optional. A property that normally returns an Int will return an Int? when accessed through optional chaining.

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()
let roomCount = john.residence!.numberOfRooms // forced unwrapping
// this triggers a runtime error

if let roomCount = john.residence?.numberOfRooms { // optional chaining
    print("John's residence has \(roomCount) room(s).")
} else {
    print("Unable to retrieve the number of rooms.")
}
// Prints "Unable to retrieve the number of rooms."

References

https://www.edwith.org/boostcamp_ios/lecture/11240
https://www.edwith.org/boostcamp_ios/lecture/11311
https://docs.swift.org/swift-book/LanguageGuide/OptionalChaining.html

0개의 댓글