2014-11-24 12 views

Odpowiedz

20

Aktualizacja Swift 1.2:

Od Swift 1.2 (Xcode 6.3 Beta), można rozpakować wieloma ewentualne, z if let:

if let foo = fooOptional, bar = barOptional { 
    println("\(foo), \(bar)") 
} 

Przed Swift 1.2

Nie można z if, ale można z switch użyciu "Value-Binding Pattern":

switch (fooOptional, barOptional) { 
case let (.Some(foo), .Some(bar)): 
    println("\(foo), \(bar)") 
default: 
    break 
} 
+0

Twoja odpowiedź jest lepsza niż moja!:) – matt

+0

Możesz z Swift 1.2, który właśnie został wydany! http://www.codingexplorer.com/multiple-optional-bindings-swift-1-2/ (Wiem, że to pytanie jest stare, ale na wszelki wypadek, jeśli ktoś przyjdzie, możesz zaktualizować swoją odpowiedź) – SeeMeCode

0

To bardzo rozsądna prośba o ulepszenie, ale w obecnej sytuacji nie można tego zrobić. Jest wiele różnych powodów, ale sposób, w jaki lubię o tym myśleć, jest następujący: if let to naprawdę jedno słowo. To dwa słowa, ale kolokacja to coś specjalnego, jakby samo słowo kluczowe. Sam w sobie, if ma inne znaczenie; samo w sobie, let ma inne znaczenie. Dlatego nie można umieścić osobnego let później w takiej linii.

Powoduje to, że często kończę kaskadami zagnieżdżonych klauzul if let. Jestem pewien, że powodem twojego pytania jest to, że ty też to robisz i chciałbyś tego uniknąć. Ale nie możesz. Jedną z możliwości jest całkowite pominięcie if let, odfiltrowanie swoich opcji i mieć nadzieję, że nie ulegniesz awarii, gdy jeden z nich będzie zerowy.

+0

Dzięki za odpowiedź. btw widziałem następujący kod - https://gist.github.com/jhaberstro/878f7f2043f922f0d06c ale komentarz mówi "segfault - wydaje się być błąd kompilatora w kodzie-gen" – FrozenHeart

6

To trochę niezgrabne, ale można to zrobić z switch na krotki swoich zmiennych:

var fooOptional: String? = "foo" 
var barOptional: String? = "bar" 

switch (fooOptional, barOptional) { 
case let (.Some(foo), .Some(bar)): 
    println(foo + bar) 
default: 
    break 
} 

Czas Używam tego wiercenia w dół do zagnieżdżonego słownika , jak wielki obiekt JSON - to super, bo można obsługiwać każdy przypadek błędu oddzielnie:

switch (dict["foo"], dict["foo"]?["bar"], dict["foo"]?["bar"]?["baz"]) { 
case let (.Some(foo), .Some(bar), .Some(baz)): 
    // do things 
case (.None, _, _): 
    // no foo 
case (_, .None, _): 
    // no bar 
default: 
    // no baz 
} 
2

Przed Swift 1.2

Lubię używać do tego oświadczenia switch, szczególnie jeśli chcesz obsłużyć cztery różne przypadki.

Jednakże, jeśli jesteś zainteresowany jedynie w przypadku, gdy oba OPCJE są Some, można też to zrobić:

if let (firstName, lastName) = unwrap(optionalFirstName, optionalLastName) { 
    println("Hello \(firstName) \(lastName)!") 
} 

Gdzie to jest definicja funkcji unwrap:

func unwrap<T1, T2>(optional1: T1?, optional2: T2?) -> (T1, T2)? { 
    switch (optional1, optional2) { 
    case let (.Some(value1), .Some(value2)): 
    return (value1, value2) 
    default: 
    return nil 
    } 
} 

Więcej przeciążeń: https://gist.github.com/tomlokhorst/f9a826bf24d16cb5f6a3

+1

Podoba mi się to opcja, gdy chcesz zaimplementować przypadek "jeśli wszystkie są dostępne", przełącznik z domyślnym kodem wydaje się być przesadą, a to utrzymuje twój kod w czystości. –

Powiązane problemy