제목: Pretty much every way to assign optionals

Non-옵셔널을 저장하거나 옵셔널을 옵셔널에 저장하기

기본적인 것이다. 로켓과학처럼 복잡한 것이 아니다.
optItem = 5 // optItem is now .some(5)
optItem = optValue // optItem is whatever optValue is
요약
사용빈도: 모든 경우
터무니없는 접근법인가: 전혀 그렇지 않다.

옵셔널을 non-옵셔널에 저장하기
많은 함수와 메소드들이 옵셔널 값을 반환한다. throw와 함께 try?를 사용할때도 옵셔널 값을 반환한다. 여러분은 종종 그 결과를 non-옵셔널 변수 혹은 프로퍼티로 담아둬야 할 때가 있을 것이다.

이렇게하기위해 nil을 테스트하고 어떤 non-nil 결과의 언랩핑된 결과를 저장한다. 아래에 몇가지 방법이 있다.

조건부의 바인딩
if let을 사용하여 조건부로 옵셔널을 바인딩하고 대입을 실행할 수 있다.
if let optItem = optItem { 
    item = optItem // if optItem is non-nil
}
if let과 완전히 동일하지만 그래도 여러분이 원한다면 if case도 사용할 수 있다.
// Sugared optional
if case let optItem? = optItem { 
    item = optItem // if optItem is non-nil
}

// External let
if case let .some(optItem) = optItem {
    item = optItem // if optItem is non-nil
}

// Internal let
if case .some(let optItem) = optItem { 
    item = optItem // if optItem is non-nil 
}

Nil coalescing
만일의 대비의 값으로 nil coalescing을 사용할 수 있다.
item = optItem ?? fallbackValue
만일의 대비의 값이 필요없다면 원래 값을 사용해도 된다.
item = optItem ?? item
약간의 주의. 컴파일러가 "자신에 자신을 할당하는" 경우를 최적화하는지 잘 모르겠다. 그것을 확인하고 할당한다면 if let 방법보다 덜 효율적일 것이다.

또한 이 Itemnon-nil 일때만 갱신한다는 의도가 추가적인 if let을 쓰는게 깔끔하다고 생각하므로 효율면이나 가독성면에서 이것을 추천하진 않는다.

요약
사용빈도: 종종 사용한다
터무니없는 접근법인가: 전혀 아니다

optItemnon-nil일때만 옵셔널을 갱신하기
이번에는 현재 옵셔널이 nil일때 갱신을 스킵하는 시나리오에대해 설명하겠다. 이러한 경우 nil은 "이 옵셔널을 건드리지 마시오"라는 의미이다. 나는 이런 시나리오가 일어나지 않게 생각했다.

명확한 해결 방법이다.
if optItem != nil { optItem = newValue }
? 표시를 사용한 완전히 이상한 벙법이다.
optItem? = nonOptionalValue
?의 사용에서 rhs는 반드시 non-옵셔널이어야하고 컴파일 시점에 보장된다. 스위프트 언어의 특징중에 다소 모호한 것이다(이것을 짚어준 Joe Groff에게 감사하다).

혹은 "non-nil 수신자를 위한 테스트" 대입을 위해 이렇게 할 수 있다(바보같지만).
if let optValue = optValue {
    optItem? = optValue
}
이 예제는, rhs? 대입은 non-옵셔널이여야한다. 조건부로 옵셔널을 바인딩하는 것은 ?을 쓸 수 있게 해준다. Madalin Sava가 아래의 간단한 대안을 알려주었다. (이 섹션의 모든 것이 그렇듯) 절약 면에서는 높은 점수지만 명료하지 않은 결과에대해서는 낮은 점수를 받는다.
optItem? = optValue ?? optItem!
요약
사용빈도: 절대 사용하지 말라
터무니없는 접근법인가: 확실히 그렇다

optItemnil일때만 옵셔널을 갱신하기
이번에는 "대부분 사용하는, 한번만 세팅하기"로 설명할 수 있겠다. 옵셔널이 non-nil 값으로 한번 대입하게 되면, 그것은 다시 덮어쓰이지 않게 만든다. 대입을 하기 전에 nil을 확인하여 가장 간단하게 할 수 있다.
if optItem == nil { optItem = newValue }

혹은 오퍼레이터로 불태워도 된다. 아마 이렇게 하고 싶진 않을 것이다.

infix operator =?? : AssignmentPrecedence

// "fill the nil" operator
public func =??<T>(target: inout T?, newValue: T?) {
    if target == nil { target = newValue }
}
optItem =?? newValue

이것도 한번 보자: SE-0024

요약
사용빈도: 나는 이렇게 사용하진 않으나, 다시 대입되는 것을 막고 싶을때 유용할 것이다. 이것이 묵시적으로 언랩핑된 옵셔널의 미친 버전의 종류이나, 그것을 다시는 바꾸지 않는다고 보장함을 테스트하는 곳과, (IVO의) 모든 일련의 변화가 non-nil 값이여야하는 곳이 아닌..
터무니없는 접근법인가: 터무니없지는 않으나 일반적이지도 않다.

새로운 값이 non-nil일때만 옵셔널을 갱신하기
이 시나리오는 기본적으로 묵시적인 언랩핑된 옵셔널을 따라한 것이지만 세이프티가 추가되고 IVO 크레쉬가 없다. 항상 non-nil에대한 테스트를 하기때문에 그 값을 검증하여 한번 세팅하면 옵셔널이 다시는 nil을 반환하지 않을 것이다.

한계는 non-nil의 새 값을 갱신하고 nil 대입을 버린다.
if let newValue = newValue { optItem = newValue }

혹은 이렇게(nil-값을 위해 다시 대입하는 행위를 한다는게 낭비처럼 느껴지지 않는가?)
optItem = newValue ?? optItem
혹은 연산자로 불태워도 된다. 마찬가지로 이렇게 하고 싶지는 않을 것이다.
infix operator =? : AssignmentPrecedence

// "assign non-nil values" operator
public func =?<T>(target: inout T, newValue: T?) {
    if let newValue = newValue {
        target = unwrapped
    }
}
이것도 한번 보자 : Swift Evolution

요약
사용빈도: 내가 사용하진 않는다만 non-IVO 옵셔널을 사용하고 싶은 사람들이 원할 수도 있을 것 같다.
터무니없는 접근법인가: 그렇진 않으나 일반적이지도 않다.


'Swift와 iOS > Swift Basic' 카테고리의 다른 글

[번역]No-contiguous raw value enumeration  (372) 2017.05.13

WRITTEN BY
tucan.dev
개인 iOS 개발, tucan9389

,