2014-12-01 12 views
8

Podczas oglądania wideo Apple'a na temat debuggera LLDB znalazłem coś, czego nie potrafię znaleźć; mówił o wartościach opcjonalnych, gdy pisał:Dwa (lub więcej) opcji w Swift

var optional: String? = nil; //This is ok, a common optional 
var twice_optional: String?? = nil; //What is this and why's this useful?? 

Otworzyłem plac zabaw i zaczął próbuje ją i zrozumiał, że można napisać tyle, ile ? jak chcesz, a następnie rozpakować je z taką samą liczbą ! . Rozumiem pojęcie zawijania/rozpakowywania zmiennej, ale nie mogę wymyślić sytuacji, w której chciałbym zawinąć wartość 4, 5 lub 6 razy.

Odpowiedz

10

(Aktualizacja dla Swift 2.)

"Double OPCJE" może być przydatna, a wpis w blogu Swift "Optionals Case Study: valuesForKeys" opisuje aplikację.

Oto uproszczony przykład:

let dict : [String : String?] = ["a" : "foo" , "b" : nil] 

jest słownikiem z opcjonalnymi ciągi jako wartości. Dlatego

let val = dict[key] 

ma typ String?? aka Optional<Optional<String>>. Jest .None (lub nil) , jeśli klucz nie jest obecny w słowniku, a .Some(x) w przeciwnym razie. W drugim przypadku x jest String? aka Optional<String> i może być .None (lub nil) lub .Some(s) gdzie s jest String.

Można używać zagnieżdżonych opcjonalne wiązanie do sprawdzenia różnych przypadkach:

for key in ["a", "b", "c"] { 

    let val = dict[key] 
    if let x = val { 
     if let s = x { 
      print("\(key): \(s)") 
     } else { 
      print("\(key): nil") 
     } 
    } else { 
     print("\(key): not present") 
    } 

} 

wyjściowa:

a: foo 
b: nil 
c: not present 

To może być pouczające, aby zobaczyć jak to samo można osiągnąć dopasowując wzór w instrukcja zmiany:

let val = dict[key] 
switch val { 
case .Some(.Some(let s)): 
    print("\(key): \(s)") 
case .Some(.None): 
    print("\(key): nil") 
case .None: 
    print("\(key): not present") 
} 

lub przy użyciu x? wzór jako synonim dla .Some(x):

let val = dict[key] 
switch val { 
case let (s??): 
    print("\(key): \(s)") 
case let (s?): 
    print("\(key): nil") 
case nil: 
    print("\(key): not present") 
} 

(nie wiem sensowny wniosek o głębiej zagnieżdżonych optionals.)

+0

Co więcej, aby być wyczerpującym, należy spróbować? ... tak jak? ... 'zwróci podwójną Opcjonalnie. –

+0

@ Cœur: Tak, ale można to rozwiązać za pomocą nawiasów: 'if let value = (try? ...) as? ... {...} ', ponieważ opcjonalne powiązanie opcjonalne nie dodaje kolejnego opcjonalnego poziomu. –

+0

Następnie inny przykład, "UIApplication.shared.delegate? .window" jest podwójnym opcjonalnym. Będziesz musiał dodać '??', aby rozwinąć okno. –

1
var tripleOptional: String??? 

jest taka sama jak

var tripleOptional: Optional<Optional<Optional<String>>> 

Nie mogę myśleć o jakiejkolwiek użytecznej korzystanie z niej, ale jej tam, bo OPCJE są ogólne praca dla każdego rodzaju obiektu. Zagnieżdżone opcje są jak pola umieszczone w innym polu lub tablicy, ale w innej tablicy.

+0

Tak, masz rację. Ale nawet tablice tablic tablic mogą być przydatne w niektórych sytuacjach. Biorąc pod uwagę, że opcje są wbudowane w języku, myślę, że mogły kontrolować, ile razy można zawijać wartość w opcjonalnym typie, nawet jeśli opcjonalny akceptuje dowolny typ.Zobaczmy, czy ktoś otworzy nasze oczy. – Sherekan

Powiązane problemy