2014-11-15 13 views
62

W Swift, jak mogę napisać case w instrukcji switch, która testuje wartość przełączaną na zawartość opcjonalnie , pomijając przypadek, jeśli opcjonalny zawiera nil?Swift: testowanie wartości opcjonalnej w przypadku przełącznika

Oto jak sobie wyobrazić, że to może wyglądać:

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 
} 

Gdybym tylko napisać go dokładnie tak, kompilator narzeka, że ​​someOptional nie jest rozpakowany, ale jeśli wyraźnie rozpakować go dodając ! do końca, Oczywiście pojawia się błąd runtime w dowolnym momencie someOptional zawiera nil. Dodanie ? zamiast ! mogłoby mieć dla mnie sens (w duchu opcjonalnego łączenia, jak przypuszczam), ale nie powoduje, że błąd kompilatora zniknie (tj. W rzeczywistości nie rozwija opcjonalnego).

Odpowiedz

80

Opcjonalnie jest tylko enum tak:

enum Optional<T> : Reflectable, NilLiteralConvertible { 
    case None 
    case Some(T) 

    // ... 
} 

Więc można dopasować je jako zwykłe wzory "Associated Values" Dopasowanie:

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") 
} 

Jeśli chcesz dopasować od someValue korzystając guard expression:

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

i Swift> 2,0

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

Należy zauważyć, że w Swift 3, niektóre/none są małe, to znaczy, że używasz .some zamiast .Some – Adam

26

Na Xcode 7 (z beta 1 Uwagi uwalnianiu), „A new x? wzór może być użyty do dopasowania wzorca na optionals jako synonim .Some(x)”. Oznacza to że w Xcode 7 i później następujące odmianą rintaro's answer będzie działać także:

switch someOptional { 
case someValue?: 
    print("the value is \(someValue)") 
case let val?: 
    print("the value is \(val)") 
default: 
    print("nil") 
} 
+2

pytanie jest o dopasowując wartość nie-opcjonalną do opcjonalnej, ta odpowiedź jest odwrotna. –

+2

To prawda, jednak ta odpowiedź została pierwotnie napisana przez OP jako aktualizacja tego pytania, więc dla niego było to niezaprzeczalnie możliwe rozwiązanie; Właśnie przeniosłem to do społecznościowej odpowiedzi wiki. Być może @GeorgeWS może wyjaśnić, dlaczego przełączanie argumentów przełącznika i przypadku działa na jego przypadek użycia? –

+0

Jestem trochę zagubiony. jaka jest różnica między Twoimi pierwszymi dwoma przypadkami? "someValue?" to jakaś inna zdefiniowana wartość, ale "case let val?" to po prostu bezpieczna, nieopakowana wersja 'someOptional' ?! – Honey