본문 바로가기

TIL

Optional

enum Optional<Wrapped>: ExpressibleByNilLiteral {
		case none
		case some(Wrapped)
}
  • 해당 값이 비어있을 수 있음을 명시할 수 있음
  • 옵셔널 타입의 경우 nil을 할당할 수 있음
  • 옵셔널 타입의 기본값을 제공하지 않으면 자동으로 nil이 기본값
  • 옵셔널 타입은 non-옵셔널 타입과 혼재하여 사용할 수 없음
  • 옵셔널 타입은 2가지의 case를 갖는 열거형
    // 아래와 같이 사용 가능
    let number: Int? = Optional.some(42)
    let noNumber: Int? = Optional.none
    print(noNumber == nil)
    // Prints "true"
    
  • → none : nil과 동일 / some(Wrapped) : wrapping된 값을 저장

Optional Binding

  • if 구문
  • guard 구문
  • while 구문
  • switch 구문
var implicitlyUnwrappedOptionalValue: Int? = 100

switch implicitlyUnwrappedOptionalValue {
case .none:
    print("This Optional variable is nil")
case .some(var value):
    value += 1
	// 101
}

Optional Chaining

  • chaining을 사용하여 wrapping값에 접근
if imagePaths["star"]?.hasSuffix(".png") == true {
    print("The star image is in PNG format")
}
// Prints "The star image is in PNG format"

Fallback Value

  • ?? : nil-coalescing 연산자
  • → 옵셔널의 인스턴스가 nil인 경우 기본값을 제공

Force Unwrapping

  • ! : fatalError(_:file:line:)의 약자
  • 인스턴스의 값이 있다고 확신하는 경우 강제 언래핑을 사용
  • 단 nil값이 나오게 되면 런타임 에러가 발생할 수 있음
  • 선언 시 강제 언래핑 타입으로 지정하는 것이후 사용 시 non 옵셔널 타입처럼 사용이 가능ex. IBoutlet하지만 확실한 값이 있을 것이라 생각하기때문에 강제추출 사용
  • : View 라이프 사이클이 loadView 전에는 nil, super.loadView 이후에는 메모리에 올라가면서 값이 생김
  • var implicitlyUnwrappedOptionalValue: Int! = 100 // 기존 변수처럼 사용 가능 implicitlyUnwrappedOptionalValue = implicitlyUnwrappedOptionalValue + 1 // nil 할당 가능 implicitlyUnwrappedOptionalValue = nil
  • → 초기값을 할당하기 전 해당 인스턴스가 nil값이 들어올 수 있는 타입으로 만들지만,

Implicitly Unwrapped Optionals

  • ? → 이를 사용하여 wrapping되지 않은 선택적 값을 사용
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // Requires explicit unwrapping

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // Unwrapped automaticallyㅌ₩

  • collection에서 map, flatmap, compactmap과 별개

map(_:)

  • 옵셔널 타입의 인스턴스를 받아서 nil이 아닐 때 클로저를 실행 후, 옵셔널 타입으로 반환
func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?
  • 옵셔널 타입이 아닌 값을 반환하는 클로저를 사용
let possibleNumber: Int? = Int("42")
let possibleSquare = possibleNumber.map { $0 * $0 }
print(possibleSquare)
// Prints "Optional(1764)"

let noNumber: Int? = nil
let noSquare = noNumber.map { $0 * $0 }
print(noSquare)
// Prints "nil"

flatMap(_:)

  • 옵셔널 타입의 인스턴스를 받아서 nil이 아닐 때 클로저를 실행 후, 옵셔널 타입으로 반환
func flatMap<U>(_ transform: (Wrapped) throws -> U?) rethrows -> U?
  • 옵셔널 값을 반환하는 클로저를 사용
let possibleNumber: Int? = Int("42")
let nonOverflowingSquare = possibleNumber.flatMap { x -> Int? in
    let (result, overflowed) = x.multipliedReportingOverflow(by: x)
    return overflowed ? nil : result
}
print(nonOverflowingSquare)
// Prints "Optional(1764)"

@autoclosure

func ten() -> Int {
    print("ten 호출")
    return 10
}

func someFunction(_ leteral: Int) {
    print("leteral 호출")
    print(leteral)
}

func someFunction(_ closure: () -> Int) {
    print("closure 호출")
    print(closure())
}

func someFunction(auto closure: @autoclosure () -> Int) {
    print("autoclosure 호출")
    print(closure())
}

someFunction(ten())
print("---")
someFunction(ten)
print("---")
// @autoclosure를 사용하여 인스턴스를 클로저로 감쌀 수 있다
// 클로저로 감쌌기 때문에 someFunction안에서 클로저를 부르는 시점을 정할 수 있다
someFunction(auto: ten())

Outlets


Documentation

Optional | Apple Developer Documentation

728x90

'TIL' 카테고리의 다른 글

MVC  (0) 2023.11.10
Architecture Pattern  (0) 2023.11.10
TCP/IP, UDP  (0) 2023.10.01
typealias  (0) 2023.10.01
AppDelegate  (0) 2023.10.01