Swift에서 Optional에 기본값을 제공 하시겠습니까?


141

Swift에서 옵션을 처리하는 관용구가 너무 장황한 것처럼 보입니다. 원하는 것이 기본값이 아닌 경우 기본값을 제공하는 것입니다.

if let value = optionalValue {
    // do something with 'value'
} else {
    // do the same thing with your default value
}

불필요하게 코드를 복제하거나

var unwrappedValue
if let value = optionalValue {
    unwrappedValue = value
} else {
    unwrappedValue = defaultValue
}

unwrappedValue상수 가 필요 하지 않습니다.

스칼라의 옵션 모나드 (Swift의 옵션과 기본적으로 같은 아이디어)는 getOrElse이 목적을위한 방법 을 가지고 있습니다 :

val myValue = optionalValue.getOrElse(defaultValue)

뭔가 빠졌습니까? 스위프트는 이미 그렇게하는 간단한 방법을 가지고 있습니까? 아니면, getOrElse선택에 대한 확장에서 정의 할 수 있습니까?


답변:


289

최신 정보

Apple은 이제 통합 연산자를 추가했습니다.

var unwrappedValue = optionalValue ?? defaultValue

이 경우 삼항 연산자는 당신의 친구입니다

var unwrappedValue = optionalValue ? optionalValue! : defaultValue

Optional 열거 형에 대한 고유 한 확장을 제공 할 수도 있습니다.

extension Optional {
    func or(defaultValue: T) -> T {
        switch(self) {
            case .None:
                return defaultValue
            case .Some(let value):
                return value
        }
    }
}

그럼 당신은 할 수 있습니다 :

optionalValue.or(defaultValue)

그러나 다른 개발자가 or방법 을 조사하지 않고도 훨씬 빨리 이해할 수 있으므로 삼항 연산자를 고수하는 것이 좋습니다.

참고 : 나는 시작 모듈 과 같은 일반적인 도우미를 추가 할 orOptional신속로합니다.


내 complier는 unwrappedValueSwift 1.2 에서이 유형의 유형이 여전히 선택적 유형 임을 보여줍니다 var unwrappedValue = optionalValue ? optionalValue! : defaultValue(xcode 6 beta 4). 이것이 바뀌 었습니까?
SimplGy

2
내 버전이 잘못되었습니다. 나는 6.4에있다. 주의 : ??기본 형식 유추 동작은 일반적으로 원하는 것이 아닌 선택 사항을 반환한다는 것입니다. 변수를 선택 사항이 아닌 것으로 선언 할 수 있으며 이는 잘 작동합니다.
SimplGy

29

2014 년 8 월 Swift는이를 지원하는 통합 연산자 (??)를 보유하고 있습니다. 예를 들어 선택적 문자열 myOptional의 경우 다음과 같이 작성할 수 있습니다.

result = myOptional ?? "n/a"

4

당신이 쓴 경우 :

let result = optionalValue ?? 50

그리고 optionalValue != nil다음 result될 것입니다 optional너무 당신은 미래에 랩을 해제해야합니다

그러나 당신은 연산자를 쓸 수 있습니다

infix operator ??? { associativity left precedence 140 }

func ???<T>(optLeft:T?, right:T!) -> T!
{
    if let left = optLeft
    {
        return left
    }
    else { return right}
}

이제 다음을 수행 할 수 있습니다.

 let result = optionalValue ??? 50

그리고 때 optionalValue != nil다음이 result될 것입니다unwraped


3

다음은 작동하는 것 같습니다

extension Optional {
    func getOrElse<T>(defaultValue: T) -> T {
        if let value = self? {
            return value as T
        } else {
            return defaultValue
        }
    }
}

그러나 캐스팅의 필요성 value as T은 추악한 해킹입니다. 이상적으로 T선택 사항에 포함 된 유형과 동일한 주장 방법이 있어야합니다 . 그대로, TgetOrElse에 제공된 매개 변수를 기반으로 추론 집합을 입력 한 다음 선택 사항과 일치하지 않고 선택 사항이 0이 아닌 런타임에 실패합니다.

let x: Int?

let y = x.getOrElse(1.414) // y inferred as Double, assigned 1.414

let a: Int? = 5

let b: Double = a.getOrElse(3.14) // Runtime failure casting 5 to Double

T메소드 를 지정할 필요가 없습니다 . 실제로 T는 Optional 의 기존 항목보다 우선합니다 . 당신은 할 수 있습니다 : func getOrElse(defaultValue: T) -> T그럼 T는 옵션의 실제 값 유형을 참조하고 당신은 그것을 확인할 필요가 없습니다
drewag

감사! 나는 당신의 응답의 후반부에서 그것을 정확하게 추론했습니다. 제네릭 형식이 T그 와 같이 정의되어 있음을 알기 위해 Optional의 정의를 검사하는 방법 이 있습니까? (간단히 컨벤션에 기반한 것으로 가정)
Wes Campaigne

OptionalXcode 내부 에서 명령을 클릭 하면 다음과 같이 정의됩니다.enum Optional<T>
drewag

아, 훌륭합니다. 나는 짐작해야했다. 거기에있는 정의가 유용 할 것입니다. 아직 문서에없는 것들이 많이 있습니다. 다시 감사합니다.
Wes Campaigne
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.