Swift : 스위치 케이스의 옵션 값에 대한 테스트


94

Swift에서, optional 의 내용에 대해 전환되는 값을 테스트하는 switch 문 에 case를 작성하고 선택 사항에 포함 된 경우 case를 건너 뛰려면 nil어떻게해야합니까?

이것이 어떻게 보일지 상상해보십시오.

let someValue = 5
let someOptional: Int? = nil

switch someValue {
case someOptional:
    // someOptional is non-nil, and someValue equals the unwrapped contents of someOptional
default:
    // either, someOptional is nil, or someOptional is non-nil but someValue does not equal the unwrapped contents of someOptional
}

난 그냥 정확히처럼 작성하는 경우, 컴파일러는 불평 someOptional풀어 아니지만, 명시 적으로 포장을 벗긴 추가하여 경우 !물론 런타임 오류의 말에, 나는 어떤 시간이 someOptional포함되어 있습니다 nil. ?대신 추가 하는 것은 !나에게 의미가 있지만 (선택적 체인의 정신으로), 컴파일러 오류가 사라지는 것은 아닙니다 (즉, 실제로 선택 사항을 풀지 않음).

답변:


113

선택 사항은 다음 enum과 같습니다.

enum Optional<T> : Reflectable, NilLiteralConvertible {
    case none
    case some(T)

    // ...
}

따라서 일반적인 "연관된 값" 일치 패턴 으로 일치시킬 수 있습니다 .

let someValue = 5
let someOptional: Int? = nil

switch someOptional {
case .some(someValue):
    println("the value is \(someValue)")
case .some(let val):
    println("the value is \(val)")
default:
    println("nil")
}

당신은에서 일치하려는 경우 someValue사용, 보호 식을 :

switch someValue {
case let val where val == someOptional:
    println(someValue)
default:
    break
}

그리고 Swift> 2.0

switch someValue {
case let val where val == someOptional:
    print("matched")
default:
    print("didn't match; default")        
}

5
Swift 3에서 some / none은 소문자입니다. 즉 .Some 대신 .some을 사용합니다.
Adam

55

Xcode 7부터 "새로운 x?패턴을 사용하여 선택 사항에 대한 패턴 일치를 .some(x)" 의 동의어로 사용할 수 있습니다 . 이것은 Swift 2 이상에서 다음과 같은 rintaro의 답변 변형 도 작동 한다는 것을 의미합니다 .

let knownValue = 5

switch someOptional {
case knownValue?:
    // Contents of someOptional are knownValue, defined above.
case let otherValue?:
    // Contents of someOptional are *any* non-nil value not already tested for.
    // Unwrapped contents are assigned to otherValue for use inside this case.
default:
    // someOptional is nil.
}

3
질문은 선택 사항이 아닌 값을 선택 사항과 일치시키는 것입니다.이 대답은 반대입니다.
Martin R

2
사실, 그러나이 답변은 원래 OP가 질문에 대한 업데이트로 작성했기 때문에 그에게 반박 할 수없는 해결책이었습니다. 방금 커뮤니티 위키 답변으로 옮겼습니다. 아마도 @GeorgeWS는 스위치 및 케이스 인수를 전환하는 것이 그의 유스 케이스에서 작동하는 이유를 명확히 할 수 있습니까?
Slipp D. Thompson 17.02.20

2
나는 조금 길을 잃었다. 처음 두 사례의 차이점은 무엇입니까? someValue?다른 정의 된 값이지만, case let val?단지 안전 풀어 버전입니다 someOptional?!
Honey

@Honey 실제 코드 예제가 아닙니다. 그것은 rintaro의 대답에 대한 단순한 변형입니다. 그러니 그 / 그녀에게 그 질문을하십시오. 제 대답은 그 / 그녀의 코드와 기능적으로 동일합니다. 린타로에게 물어 보면 대답은 1이 될 것이라고 믿습니다. 링크 된 Apple 문서에있는 내용을 반영합니다. 2. 단지 구문을 보여줍니다. 뚜렷한 계산 또는 비즈니스 논리 목표를 달성하지 못합니다.
Slipp D. Thompson

@Honey 또한 rintaro의 답변은 원래 Swift 1.x 용으로 작성되었고 Swift 2 용으로 업데이트되었습니다. 버전이 let더 이상 컴파일되지 않을 수도 있습니다. 그게 왜 과거로 돌아 왔는지 지금은 기억이 나지 않습니다.
Slipp D. Thompson 2018

10

Swift 4 에서는 Optional : ExpressibleByNilLiteral of Apple을 사용하여 선택 사항 을 래핑 할 수 있습니다 .

https://developer.apple.com/documentation/swift/optional

enum MyEnum {
    case normal
    case cool
}

약간

let myOptional: MyEnum? = MyEnum.normal

switch smyOptional {
    case .some(.normal): 
    // Found .normal enum
    break

    case .none: 
    break

    default:
    break
}

없음

let myOptional: MyEnum? = nil

switch smyOptional {
    case .some(.normal): 
    break

    case .none: 
    // Found nil
    break

    default:
    break
}

기본

let myOptional: MyEnum? = MyEnum.cool

switch smyOptional {
    case .some(.normal): 
    break

    case .none: 
    break

    default:
    // Found .Cool enum
    break
}

값이있는 열거 형

enum MyEnum {
    case normal(myValue: String)
    case cool
}

어떤 가치

let myOptional: MyEnum? = MyEnum.normal("BlaBla")

switch smyOptional {
case .some(.normal(let myValue)) where myValue == "BlaBla":
    // Here because where find in my myValue "BlaBla"
    break

// Example for get value
case .some(.normal(let myValue)):
    break

// Example for just know if is normal case enum
case .some(.normal):
    break

case .none:
    break

default:

    break
}

언급 ExpressibleByNilLiteral했지만 실제로 열거 형 선언 등에 사용되지 않습니다. 그게 뭐죠?
pkamb
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.