Praca z typami opcjonalnymi może się wydawać momentami bardzo niezgrabna. Całe to rozpakowywanie i sprawdzanie może stać się tak uciążliwe, że dorzucenie jednego czy dwóch wykrzykników tu i tam, żeby ułatwić sobie pracę będzie bardzo kuszące. Uważaj jednak: jeśli wymusisz rozpakowanie na typie opcjonalnym, który nie będzie miał wartości, Twój kod przestanie działać.
Swift posiada dwie techniki, które sprawią, że Twój kod będzie mniej skomplikowany. Pierwsza to wiązanie typów opcjonalnych (z ang. Optional chaining), które pozwoli Ci na wykonanie kodu do momentu gdy typ opcjonalny będzie posiadał wartość.
Przenieś poniższy kod do Twojego playgroundu:
func albumReleased(year: Int) -> String? {
switch year {
case 2006: return "Taylor Swift"
case 2008: return "Fearless"
case 2010: return "Speak Now"
case 2012: return "Red"
case 2014: return "1989"
default: return nil
}
}
let album = albumReleased(year: 2006)
print("The album is \(album)")
Pokaże on "The album is Optional("Taylor Swift")" w panelu z wynikami.
Jeśli chcielibyśmy zamienić zwracany ciąg znaków z albumReleased()
na wielkie litery (tzn. na "TAYLOR SWIFT" zamiast "Taylor Swift"), moglibyśmy wywołać metodę uppercased()
na tym ciągu. Na przykład:
let str = "Hello world"
print(str.uppercased())
Jest jeden problem - albumReleased()
zwraca opcjonalny ciąg znaków: może zwrócić ciąg znaków albo nie zwrócić nic. Więc, to co mamy na myśli to: "jeśli mamy ciąg znaków, zamień wszystkie znaki na wielkie litery, w przeciwnym wypadku nie rób nic." To jest moment, w którym wiązanie typów opcjonalnych może nam pomóc.
Spróbuj zamienić dwie ostatnie linie kodu na:
let album = albumReleased(year: 2006)?.uppercased()
print("The album is \(album)")
Zauważ, że pojawił się tam znak zapytania, który oznajmia użycie wiązania typu opcjonalnego: wszystko co znajduje się za tym znakiem będzie wykonane tylko i wyłącznie wtedy gdy to co się przed nim znajduje posiada wartość.
Twoje wiązania typów opcjonalnych mogą być tak długie jak tego chcesz, przykładowo:
let album = albumReleased(year: 2006)?.someOptionalValue?.someOtherOptionalValue?.whatever
Język Swift sprawdzi powyższe wyrażenie od lewej do prawej aż nie znajdzie nila, wtedy zatrzyma wykonanie istrukcji.
Ten prostu akcent języka Swift uprości Twój kod i sprawi, że będzie bezpieczniejszy, a jednocześnie posiada tak skomplikowaną nazwę, że większość ludzi się go boi. Jest to wielka szkoda, bo operator koalescencyjny nil ułatwi Ci życie jeśli poświęcisz trochę czasu na jego zrozumienie!
Pozwala Ci on na powiedzenie: "Użyj wartości A jeśli to możliwe, ale jeśli wartość A jest nilem, to wtedy użyj wartości B." Tyle. Operator ten jest szczególnie przydatny przy typach opcjonalnych, ponieważ efektywnie zamienia je w typ nieopcjonalny, bo zapewniamy nieopcjonalną wartość B. Innymi słowami, jeśli A jest typem opcjonalnym i ma wartość, zostaje użyty (dostajemy wartość). Jeśli A istnieje i nie ma wartości, użyta zostaje wartość B (nadal mamy wartość). W obu tych przypadkach kończymy z pewną wartością.
Żaby podać Ci konkretny przykład, przenieś ten kod do playgroundu:
let album = albumReleased(year: 2006) ?? "unknown"
print("The album is \(album)")
Te dwa znaki zapytania to operator koalescencyjny nil, i w tym przypadku oznacza: "jeśli albumReleased()
zwróci wartość to umieść ją w zmiennej album
, ale jeśli albumReleased()
zwróci nil to zamiast tego użyj "unknown."
Jeśli spojrzysz teraz na panel z wynikami zobaczysz, że znajduje się tam wiadomość "The album is Taylor Swift" - bez typów opcjonalnych. To dlatego, że język Swift jest teraz pewny, że dostanie istniejącą wartość - albo zwróconą z funkcji albo "unknown". To z kolei oznacza, że nie musisz niczego rozpakowywać albo narażać się na zatrzymanie pracy aplikacji - masz gwarancję na to, że pracujesz z istniejącymi wartościami, co czyni Twój kod bezpieczniejszym i łatwiejszym do pracy.
SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure and A/B test your entire paywall UI without any code changes or app updates.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.