Możesz używać
if
ilet
razem do pracy z wartościami, których może brakować. Wartości te są przedstawiane jako opcje. Opcjonalna wartość zawiera wartość lub zawiera,nil
aby wskazać brak wartości. Napisz znak zapytania (?
) po typie wartości, aby oznaczyć wartość jako opcjonalną.
Dlaczego chcesz użyć wartości opcjonalnej?
Odpowiedzi:
Opcjonalny w Swift to typ, który może przechowywać wartość lub nie zawierać żadnej wartości. Opcjonalne są zapisywane przez dodanie
?
do dowolnego typu:Opcjonalne (wraz z Generics) są jedną z najtrudniejszych do zrozumienia koncepcji Swift. Ze względu na sposób, w jaki są pisane i używane, łatwo jest źle zrozumieć, jakie są. Porównaj opcjonalne powyżej z tworzeniem normalnego ciągu:
Ze składni wygląda na to, że opcjonalny ciąg znaków jest bardzo podobny do zwykłego ciągu znaków. To nie jest. Opcjonalny ciąg nie jest ciągiem z włączonymi niektórymi ustawieniami „opcjonalnymi”. To nie jest specjalna odmiana Sznurka. Ciąg i opcjonalny ciąg to zupełnie różne typy.
Oto najważniejsza rzecz, którą należy wiedzieć: Opcjonalnie jest rodzajem pojemnika. Opcjonalny ciąg to kontener, który może zawierać ciąg. Opcjonalny Int to kontener, który może zawierać Int. Pomyśl o opcjonalnym jako paczce. Zanim go otworzysz (lub „rozpakujesz” w języku opcjonalnym) nie będziesz wiedział, czy zawiera on coś, czy nic.
Możesz zobaczyć, w jaki sposób opcje są implementowane w Swift Standard Library, wpisując „Opcjonalne” w dowolnym pliku Swift i klikając go ⌘. Oto ważna część definicji:
Opcjonalne jest tylko
enum
jedno z dwóch przypadków:.none
lub.some
. Jeśli tak.some
, istnieje powiązana wartość, która w powyższym przykładzie byłabyString
„Cześć”. Opcjonalne używa Rodzajowych, aby nadać typ powiązanej wartości. Typ opcjonalnego ciągu nie jestString
, jestOptional
, a dokładniejOptional<String>
.Wszystko, co Swift robi z opcjami, to magia, dzięki której czytanie i pisanie kodu jest płynniejsze. Niestety przesłania to sposób, w jaki faktycznie działa. Później przejdę przez niektóre sztuczki.
Uwaga: Będę dużo mówił o zmiennych opcjonalnych, ale dobrze jest również tworzyć opcjonalne stałe. Zaznaczam wszystkie zmienne ich typem, aby ułatwić zrozumienie tworzonych typów typów, ale nie musisz tego robić we własnym kodzie.
Jak tworzyć opcje
Aby utworzyć opcjonalny, dodaj
?
po typ, który chcesz zawinąć. Każdy typ może być opcjonalny, nawet własne typy niestandardowe. Nie możesz mieć spacji między typem a?
.Korzystanie z opcji
Możesz porównać opcjonalny,
nil
aby sprawdzić, czy ma wartość:To jest trochę mylące. Oznacza to, że opcjonalne to jedno lub drugie. To albo zero, albo „Bob”. To nie jest prawda, opcja nie przekształca się w coś innego. Porównywanie go do zera jest sztuczką, aby uczynić kod łatwiejszym do odczytania. Jeśli opcja jest równa zero, oznacza to po prostu, że wyliczenie jest obecnie ustawione na
.none
.Tylko opcje mogą być zerowe
Jeśli spróbujesz ustawić nie opcjonalną zmienną na zero, pojawi się błąd.
Innym sposobem patrzenia na opcje jest uzupełnienie normalnych zmiennych Swift. Są odpowiednikiem zmiennej, która ma gwarantowaną wartość. Swift to ostrożny język, który nie znosi dwuznaczności. Większość zmiennych jest definiowanych jako nieopcjonalne, ale czasami nie jest to możliwe. Na przykład wyobraź sobie kontroler widoku, który ładuje obraz z pamięci podręcznej lub z sieci. Może lub nie może mieć tego obrazu w momencie tworzenia kontrolera widoku. Nie ma sposobu, aby zagwarantować wartość zmiennej obrazu. W takim przypadku należy ustawić opcję opcjonalną. Zaczyna się,
nil
gdy obraz jest pobierany, opcjonalnie pobiera wartość.Użycie opcjonalnego ujawnia zamiary programistów. W porównaniu do Celu C, w którym dowolny obiekt może być zerowy, Swift wymaga jasnego określenia, kiedy może brakować wartości i kiedy istnieje gwarancja jej istnienia.
Aby użyć opcjonalnego, „rozpakuj” go
Opcjonalnego
String
nie można użyć zamiast faktycznegoString
. Aby użyć zawiniętej wartości wewnątrz opcjonalnej, musisz ją rozpakować. Najprostszym sposobem na rozpakowanie opcjonalnego jest dodanie!
po opcjonalnej nazwie. Nazywa się to „wymuszaniem rozpakowywania”. Zwraca wartość wewnątrz opcjonalnego (jako pierwotnego typu), ale jeśli opcjonalny jestnil
, powoduje awarię środowiska wykonawczego. Przed rozpakowaniem należy upewnić się, że istnieje wartość.Sprawdzanie i korzystanie z opcjonalnego
Ponieważ zawsze należy sprawdzić zero przed rozpakowaniem i użyciem opcjonalnego, jest to powszechny wzorzec:
W tym wzorze sprawdzasz, czy wartość jest obecna, a następnie, gdy jesteś pewien, że tak jest, wymuszasz rozpakowanie jej do tymczasowej stałej do użycia. Ponieważ jest to tak powszechne, Swift oferuje skrót za pomocą „jeśli pozwala”. Nazywa się to „opcjonalnym wiązaniem”.
Tworzy to tymczasową stałą (lub zmienną, jeśli zastąpisz
let
jąvar
), której zakres znajduje się tylko w nawiasach if. Ponieważ używanie nazwy takiej jak „unwrappedMealPreference” lub „realMealPreference” jest dużym obciążeniem, Swift pozwala na ponowne użycie oryginalnej nazwy zmiennej, tworząc tymczasową w zakresie nawiasówOto kod pokazujący, że używana jest inna zmienna:
Opcjonalne wiązanie działa poprzez sprawdzenie, czy opcjonalne jest równe zero. Jeśli nie, rozpakowuje opcjonalne do podanej stałej i wykonuje blok. W Xcode 8.3 i późniejszych (Swift 3.1) próba wydrukowania takiej opcji opcjonalnej spowoduje bezużyteczne ostrzeżenie. Użyj opcji opcjonalnych,
debugDescription
aby go wyciszyć:Do czego służą opcje?
Opcjonalne mają dwa przypadki użycia:
Niektóre konkretne przykłady:
middleName
lubspouse
wPerson
klasieweak
właściwości w klasach. To, na co wskazują, można ustawićnil
w dowolnym momencieBoolean
Opcje nie istnieją w Objective-C, ale istnieje równoważna koncepcja, zwracająca zero. Metody, które mogą zwrócić obiekt, mogą zamiast tego zwrócić zero. Ma to oznaczać „brak ważnego obiektu” i często używane jest do powiedzenia, że coś poszło nie tak. Działa tylko z obiektami Objective-C, a nie z prymitywami lub podstawowymi typami C (wyliczenia, struktury). Cel C często nie wyspecjalizowane typy reprezentuje brak tych wartości (
NSNotFound
która jest naprawdęNSIntegerMax
,kCLLocationCoordinate2DInvalid
reprezentuje nieprawidłową współrzędnych-1
lub jakąś wartość ujemna są używane). Koder musi wiedzieć o tych specjalnych wartościach, dlatego należy je udokumentować i nauczyć się dla każdego przypadku. Jeśli metoda nie mogła przyjąć,nil
parametru, należy to udokumentować. W celu Cnil
był wskaźnikiem, tak jak wszystkie obiekty zostały zdefiniowane jako wskaźniki, alenil
wskazywały na określony (zerowy) adres. W Swiftnil
jest dosłowny, co oznacza brak określonego typu.W porównaniu do
nil
Kiedyś byłeś w stanie użyć dowolnej opcjonalnej jako
Boolean
:W nowszych wersjach Swift musisz używać
leatherTrim != nil
. Dlaczego to? Problem polega na tym, żeBoolean
można zawinąć w opcjonalny. JeśliBoolean
tak, to:ma dwa rodzaje „fałszu”, jeden, w którym nie ma wartości, i jeden, w którym ma wartość, ale wartość jest
false
. Szybka nienawidzi dwuznaczności, więc teraz zawsze musisz sprawdzić opcję przeciwnil
.Zastanawiasz się, jaki jest sens opcjonalności
Boolean
? Podobnie jak w przypadku innych opcji,.none
stan może wskazywać, że wartość jest jak dotąd nieznana. Na drugim końcu połączenia sieciowego może znajdować się coś, co zajmuje trochę czasu, aby sondować. Opcjonalne booleany nazywane są również „ booleanami trzech wartości ”Szybkie sztuczki
Swift wykorzystuje kilka sztuczek, aby umożliwić działanie opcji. Rozważ te trzy linie zwykłego kodu opcjonalnego;
Żadna z tych linii nie powinna się skompilować.
String
typ, są różneOmówię niektóre szczegóły implementacji opcji, które pozwalają na działanie tych linii.
Tworzenie opcjonalnego
Używanie
?
do tworzenia opcjonalnego jest cukrem syntaktycznym, włączanym przez kompilator Swift. Jeśli chcesz to zrobić na dłuższą metę, możesz utworzyć opcjonalne takie jak to:Wywołuje
Optional
to pierwszy inicjalizator,public init(_ some: Wrapped)
który wyprowadza typ opcjonalny z typu używanego w nawiasach.Jeszcze dłuższy sposób tworzenia i ustawiania opcjonalnego:
Ustawienie opcjonalne na
nil
Możesz utworzyć opcjonalny bez wartości początkowej lub utworzyć wartość początkową
nil
(oba mają ten sam wynik).Umożliwienie równości opcji
nil
jest możliwe dzięki protokołowiExpressibleByNilLiteral
(poprzednio nazwanemuNilLiteralConvertible
). Opcjonalny jest tworzony zOptional
drugim co inicjatora,public init(nilLiteral: ())
. Dokumenty mówią, że nie powinieneś używaćExpressibleByNilLiteral
do niczego oprócz opcji, ponieważ zmieniłoby to znaczenie zero w twoim kodzie, ale można to zrobić:Ten sam protokół umożliwia ustawienie już utworzonej opcji na
nil
. Chociaż nie jest to zalecane, możesz użyć inicjatora zerowego dosłowności bezpośrednio:Porównanie opcjonalnego z
nil
Opcje definiują dwa specjalne operatory „==” i „! =”, Które można zobaczyć w
Optional
definicji. Pierwszy==
pozwala sprawdzić, czy jakakolwiek opcja jest równa zero. Dwie różne opcje, które są ustawione na .none, zawsze będą równe, jeśli powiązane typy są takie same. Kiedy porównujesz do zera, za kulisami Swift tworzy opcjonalny tego samego powiązanego typu, ustaw na .none, a następnie używa go do porównania.Drugi
==
operator umożliwia porównanie dwóch opcji. Oba muszą być tego samego typu i ten typ musi być zgodnyEquatable
(protokół, który pozwala na porównanie rzeczy ze zwykłym operatorem „==”). Szybki (przypuszczalnie) rozpakowuje dwie wartości i porównuje je bezpośrednio. Obsługuje również przypadek, w którym znajduje się jedna lub obie opcje.none
. Zwróć uwagę na różnicę między porównywaniem znil
literałem.Ponadto pozwala porównać dowolny
Equatable
typ z opcjonalnym opakowaniem tego typu:Za kulisami Swift otacza nieopcjonalne jako opcjonalne przed porównaniem. Działa również z literałami (
if 23 == numberFromString {
)Powiedziałem, że są dwa
==
operatory, ale tak naprawdę jest trzeci, który pozwala umieścićnil
po lewej stronie porównaniaOpcje nazewnictwa
Nie ma konwencji Swift dotyczącej nazewnictwa typów opcjonalnych inaczej niż typów nieobowiązkowych. Ludzie unikają dodawania czegoś do nazwy, aby pokazać, że jest ona opcjonalna (np. „OpcjonalnaŚredniaNazwa” lub „możliwaNumerAsString”) i pozwalają deklaracji pokazać, że jest to typ opcjonalny. Staje się to trudne, gdy chcesz nazwać coś, co będzie zawierało wartość opcjonalną. Nazwa „middleName” implikuje, że jest to typ String, więc kiedy wyodrębnisz z niej wartość String, często możesz skończyć z nazwami takimi jak „actualMiddleName” lub „unwrappedMiddleName” lub „realMiddleName”. Użyj opcjonalnego wiązania i ponownie użyj nazwy zmiennej, aby obejść ten problem.
Oficjalna definicja
Z „Podstawy” w Swift Programming Language :
Na koniec oto wiersz z 1899 roku na temat opcji:
Wczoraj na schodach
spotkałem mężczyznę, którego tam nie było.
Nie było go dzisiaj.
Chciałbym, chciałbym, żeby odszedł
Antigonish
Więcej zasobów:
źródło
if myString
już się nie kompiluje. Trzebaif myString != nil
. Zobacz dokumentację .Weźmy przykład:
NSError
jeśli nie zostanie zwrócony błąd, możesz ustawić opcjonalne zwracanie wartości zero. Przypisywanie wartości do wartości nie ma sensu, jeśli nie ma błędu.Pozwala to również na ustawienie wartości domyślnej. Możesz więc ustawić metodę jako wartość domyślną, jeśli funkcja niczego nie przekaże
źródło
func isNil<T>(t: T?) -> Bool { return t == nil }
zwróci,true
nawet jeślinil
w wyrażeniu jest opcjonalna wartość .return x == 5
? Co jest takiego specjalnego w 5?Nie możesz mieć zmiennej, która wskazuje
nil
w Swift - nie ma wskaźników ani wskaźników zerowych. Ale w interfejsie API często chcesz być w stanie wskazać konkretny rodzaj wartości lub jej brak - np. Czy moje okno ma delegata, a jeśli tak, to kto? Opcjonalne są bezpieczne dla typu, bezpieczne dla pamięci metody Swift.źródło
Udzieliłem krótkiej odpowiedzi, która podsumowuje większość z powyższych, aby usunąć niepewność, która była w mojej głowie jako początkującego:
W przeciwieństwie do Celu-C żadna zmienna nie może zawierać wartości zerowej w Swift, dlatego dodano opcjonalny typ zmiennej (zmienne z przyrostkiem „?”):
Duża różnica polega na tym, że zmienne opcjonalne nie przechowują bezpośrednio wartości (tak jak normalne zmienne Obj-C), zawierają dwa stany : „ ma wartość ” lub „ ma zero ”:
W związku z tym możesz sprawdzić te zmienne w różnych sytuacjach:
Korzystając z „!” sufiks, możesz również uzyskać dostęp do wartości w nich zawartych , tylko jeśli one istnieją . (tzn. nie jest zero ):
Dlatego musisz użyć „?” i "!" i nie używaj ich wszystkich domyślnie. (to było moje największe oszołomienie)
Zgadzam się również z powyższą odpowiedzią: Typu opcjonalnego nie można użyć jako wartości logicznej .
źródło
W obiektywnych zmiennych C bez wartości były równe „zero” (możliwe było również użycie wartości „zero” takich samych jak 0 i fałsz), dlatego możliwe było użycie zmiennych w instrukcjach warunkowych (Zmienne o wartościach takich samych jak „PRAWDA” ”, a te bez wartości były równe„ FAŁSZ ”).
Swift zapewnia bezpieczeństwo typu, zapewniając „wartość opcjonalną”. tzn. zapobiega powstawaniu błędów spowodowanych przypisywaniem zmiennych różnych typów.
Zatem w Swift można podawać tylko wartości logiczne w instrukcjach warunkowych.
Tutaj, mimo że „hw” jest ciągiem, nie można go użyć w instrukcji if, tak jak w celu C.
W tym celu należy go utworzyć jako,
źródło
Opcjonalna wartość pozwala pokazać brak wartości. Trochę jak NULL w SQL lub NSNull w Objective-C. Myślę, że będzie to ulepszenie, ponieważ można tego użyć nawet w przypadku typów „prymitywnych”.
Fragment: Apple Inc. „Swift Programming Language”. iBooks. https://itun.es/gb/jEUH0.l
źródło
nil
to po prostu cukier składniowy dla stałej wyliczeniowejOptionalValue<T>.None
(gdzieT
jest typ odpowiedni dla kontekstu, w którym używasznil
).?
jest skrótem doOptionalValue<T>.Some(T)
.Opcjonalne oznacza, że Swift nie jest całkowicie pewien, czy wartość odpowiada typowi: na przykład Int? oznacza, że Swift nie jest całkowicie pewien, czy liczba jest liczbą całkowitą.
1) Jeśli masz absolutną pewność co do typu, możesz użyć wykrzyknika, aby wymusić jego rozpakowanie, w następujący sposób:
Jeśli wymusisz rozpakowanie opcjonalnego i jest on równy zero, możesz napotkać ten błąd awarii:
To niekoniecznie jest bezpieczne, więc oto metoda, która może zapobiec awarii w przypadku, gdy nie masz pewności co do typu i wartości:
2) Opcja niejawnie nieopakowana
3) Strażnik
Stąd możesz zacząć od rozpakowanej zmiennej. Pamiętaj, aby wymusić odwijanie (za pomocą!), Jeśli jesteś pewien typu zmiennej.
źródło
Kiedy zacząłem się uczyć
Swift
, bardzo trudno było zrozumieć, dlaczego jest to opcjonalne .Pomyślmy w ten sposób. Rozważmy klasę,
Person
która ma dwie właściwościname
icompany
.Teraz pozwala stworzyć kilka obiektów
Person
Ale nie możemy przejść
Nil
doname
Teraz Porozmawiajmy o tym, dlaczego używamy
optional?
. Rozważmy sytuację, w której chcemy dodaćInc
po nazwie firmy jakapple
będzieapple Inc
. Musimy dołączyćInc
po nazwie firmy i wydruku.Teraz zbadajmy, dlaczego ma miejsce opcjonalność.
Pozwala zastąpić
bob
ztom
I gratulacje! mamy właściwie do czynienia
optional?
Tak więc są punkty realizacji
nil
nil
.Dziękuję ... Szczęśliwego kodowania
źródło
Pozwala eksperymentować z poniższym kodem Plac zabaw. Mam nadzieję, że wyjaśnię, co jest opcjonalne i dlaczego go używam.
źródło
Od https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html :
Aby lepiej zrozumieć, przeczytaj powyższy link.
źródło
Dobrze...
Główną różnicą jest to, że opcjonalne łączenie łańcuchów kończy się niepowodzeniem, gdy opcjonalne jest zerowe, natomiast wymuszone rozpakowywanie powoduje błąd czasu wykonywania, gdy opcjonalne jest zerowe.
Aby odzwierciedlić fakt, że opcjonalne łączenie łańcuchowe można wywołać na wartość zero, wynik opcjonalnego wywołania łańcuchowego jest zawsze wartością opcjonalną, nawet jeśli właściwość, metoda lub indeks dolny, którego dotyczy zapytanie, zwraca wartość nieobowiązkową. Za pomocą tej opcjonalnej wartości zwrotnej można sprawdzić, czy opcjonalne połączenie łańcuchowe zakończyło się powodzeniem (zwrócona opcja zawiera wartość) lub nie powiodła się z powodu zerowej wartości w łańcuchu (zwrócona wartość opcjonalna to zero).
W szczególności wynik opcjonalnego połączenia łańcuchowego jest tego samego typu co oczekiwana wartość zwracana, ale jest zawarty w opcjonalnym. Właściwość, która normalnie zwraca Int, zwróci Int? przy dostępie poprzez opcjonalne łączenie.
Oto szczegółowy podstawowy samouczek opracowany przez Apple Developer Committee: Opcjonalne tworzenie łańcuchów
źródło
Opcjonalny w Swift to typ, który może przechowywać wartość lub nie zawierać żadnej wartości. Opcjonalne są napisane przez dodanie ? do dowolnego typu:
Możesz skorzystać z tego linku, aby uzyskać głębszą wiedzę: https://medium.com/@agoiabeladeyemi/optionals-in-swift-2b141f12f870
źródło
Oto równoważna opcjonalna deklaracja w Swift:
Ta deklaracja tworzy zmienną o nazwie middleName typu String. Znak zapytania (?) Po typie zmiennej String wskazuje, że zmienna middleName może zawierać wartość, która może być String lub zero. Każdy, kto patrzy na ten kod, natychmiast wie, że middleName może być zerowy. To jest samo dokumentowanie!
Jeśli nie określisz wartości początkowej dla opcjonalnej stałej lub zmiennej (jak pokazano powyżej), wartość zostanie automatycznie ustawiona na zero. Jeśli wolisz, możesz jawnie ustawić wartość początkową na zero:
Aby uzyskać więcej informacji na temat opcjonalnego przeczytaj poniższy link
http://www.iphonelife.com/blog/31369/swift-101-working-swifts-new-optional-values
źródło