Swift Optionals: jak ich używać (z przykładami)

W tym artykule dowiesz się o opcjach, ich przypadkach użycia i opcjonalnej obsłudze w Swift.

W poprzednim artykule dowiedzieliśmy się o różnych typach danych dostępnych w Swift, a także zauważyliśmy, że zmienna lub stała zadeklarowana tych typów zawiera wartość domyślną.

Przykład:

 let someValue = Int () print (someValue) 

Po uruchomieniu programu wynik będzie następujący:

 0

Jednak w języku Swift istnieje inny typ danych o nazwie Optional, którego wartością domyślną jest wartość null ( nil). Możesz użyć opcjonalnego, jeśli chcesz, aby zmienna lub stała nie zawierała żadnej wartości. Opcjonalny typ może zawierać wartość lub jej brakować (wartość pusta).

Z technicznego punktu widzenia możesz pomyśleć jako opcjonalne pudełko na buty. Pudełko na buty może, ale nie musi, zawierać but. Więc powinieneś wiedzieć wcześniej, uzyskując dostęp do buta z pudełka.

Jak zadeklarować opcjonalny?

Możesz po prostu przedstawić typ danych jako opcjonalny, dołączając !lub ?do Type. Jeśli opcja opcjonalna zawiera wartość, zwraca wartość jako Optional, jeśli nie zwraca nil.

Przykład 1: Jak zadeklarować opcję opcjonalną w Swift?

 var someValue:Int? var someAnotherValue:Int! print(someValue) print(someAnotherValue) 

Po uruchomieniu programu wynik będzie następujący:

 zero zero

W powyższym programie zainicjowaliśmy opcjonalny typ przy użyciu ?i !. Oba sposoby są prawidłowe, aby utworzyć opcjonalny, ale jest jedna główna różnica, którą zbadamy poniżej.

Zadeklarowanie opcjonalnej wartości Int oznacza, że ​​zmienna będzie miała wartość całkowitą lub nie będzie miała wartości. Ponieważ do zmiennej nie jest przypisana żadna wartość, na ekranie można zobaczyć oba printwyjścia instrukcji nil.

Przykład 2: przypisywanie i uzyskiwanie dostępu do wartości z opcjonalnego

 let someValue:Int? = 5 print(someValue) print(someValue!) 

Po uruchomieniu programu wynik będzie następujący:

 Opcjonalnie (5) 5 

W powyższym programie zadeklarowaliśmy opcjonalny Inttyp i przypisaliśmy w nim wartość 5.

Jak widać, wydrukowanie opcjonalnego as print(someValue)nie daje ci 5ale Optional(5). To jest w postaci, jak opisano powyżej: Optional. Aby uzyskać z niego dostęp , potrzebujemy mechanizmu zwanego rozpakowywaniem .

Możesz rozpakować opcjonalne, dodając !znak na końcu zmiennej / stałej, jak w następnym wierszu print(someValue!). print(someValue!)rozpakowuje opcjonalne i wyjścia 5na ekranie.

Pamiętaj jednak, że ten rodzaj mechanizmu rozpakowywania powinien być używany tylko wtedy, gdy masz pewność, że opcja będzie miała wartość, gdy uzyskasz do niej dostęp.

Przykład 3: Jawne zadeklarowanie nieopakowanego opcjonalnego

Możesz również utworzyć rozpakowany opcjonalny jako:

 let someValue:Int! = 5 print(someValue) 

Po uruchomieniu programu wynik będzie następujący:

 5

W powyższym programie Int!tworzy nieopakowane opcjonalne, które automatycznie rozpakowuje wartość podczas uzyskiwania do niej dostępu, dzięki czemu nie trzeba za każdym razem dopisywać !znaku.

Upewnij się, że używasz tego rodzaju opcji, zmienna zawsze będzie musiała mieć wartość, gdy uzyskasz do niej dostęp. Jeśli tego nie zrobisz, wystąpi krytyczny błąd.

Przykład 4: błąd krytyczny podczas uzyskiwania dostępu do nieopakowanego null opcjonalnego

 var someValue:Int! var unwrappedValue:Int = someValue //crashes due to this line 

Po uruchomieniu programu otrzymasz awarię jako błąd krytyczny: nieoczekiwanie znaleziono zero podczas rozpakowywania wartości opcjonalnej, ponieważ kod unwrappedValue:Int = someValuepróbuje przypisać wartość z Optional someValue do zmiennej unrappedValue.

Jednak somevalue jest Optionaltypem zawierającym nilwartość. Próba przypisania wartości zerowej do zmiennej unrappedValue, która nie jest opcjonalna, spowoduje awarię.

Istnieją różne techniki postępowania w tym przypadku, które zostały wyjaśnione poniżej.

Opcjonalna obsługa

Aby użyć wartości opcjonalnej, należy ją rozpakować. Lepszym sposobem użycia wartości opcjonalnej jest warunkowe rozpakowywanie zamiast wymuszania rozpakowywania przy użyciu !operatora.

Dzieje się tak, ponieważ warunkowe rozpakowanie pyta Sprawdź, czy ta zmienna ma wartość? . Jeśli tak, podaj wartość, w przeciwnym razie obsłuży przypadek zerowy.

Wręcz przeciwnie, wymuszenie rozpakowania mówi, że ta zmienna ma wartość, gdy jej używasz . Dlatego, gdy wymusisz rozpakowanie zmiennej, która jest zerowa, program wyrzuci nieoczekiwanie znalezione zero podczas rozpakowywania opcjonalnego wyjątku i awarii . Poniżej opisano niektóre techniki warunkowego rozpakowywania:

1. Instrukcja jeśli

You can use if statement and compare optional with nil to find out whether a optional contains a value or not. You can use the comparison operator "equal to" operator (==) or the "not equal to" operator (!=) in the if statement.

Example 5: Optional handling with if else statement

 var someValue:Int? var someAnotherValue:Int! = 0 if someValue != nil ( print("It has some value (someValue!)") ) else ( print("doesn't contain value") ) if someAnotherValue != nil ( print("It has some value (someAnotherValue!)") ) else ( print("doesn't contain value") ) 

When you run the program, the output will be:

 doesn't contain value It has some value 0 

In the above program, the code inside if statement executes if an optional contain a value, otherwise the statement inside the else block executes. The major drawback of optional handling using this technique is, you still need to unwrap the value from optional using ! operator.

2. Optional Binding (if-let)

Optional binding helps you to find out whether an optional contains a value or not. If an optional contains a value, that value is available as a temporary constant or variable. Therefore, optional binding can be used with if statement to check for a value inside an optional, and to extract that value into a constant or variable in a single action.

Example 5: Optional handling using if let statement

 var someValue:Int? var someAnotherValue:Int! = 0 if let temp = someValue ( print("It has some value (temp)") ) else ( print("doesn't contain value") ) if let temp = someAnotherValue ( print("It has some value (temp)") ) else ( print("doesn't contain value") ) 

When you run the program, the output will be:

 doesn't contain value It has some value 0 

In the above program, the code inside if statement executes if the optional contains a value. Otherwise the else block gets executed. The if-let statement also automatically unwraps the value and places the unwrapped value in temp constant. This technique has major advantage because you don't need to forcely unwrap the value although being certain an optional contains a value.

3. Guard statement

You can use guard to handle optionals in Swift. Don't worry if you don't know what guard is. For now, just think of guard as an if-else condition with no if block. If the condition fails, else statement is executed. If not, next statement is executed. See Swift guard for more details.

Example 6: Optional handling using guard-let

 func testFunction() ( let someValue:Int? = 5 guard let temp = someValue else ( return ) print("It has some value (temp)") ) testFunction() 

When you run the program, the output will be:

 It has some value 5

In the above program, the guard contains a condition whether an optional someValue contains a value or not. If it contains a value then guard-let statement automatically unwraps the value and places the unwrapped value in temp constant. Otherwise, else block gets executed and and it would return to the calling function. Since, the optional contains a value, print function is called.

4. Nil-coalescing operator

In Swift, you can also use nil-coalescing operator to check whether a optional contains a value or not. It is defined as (a ?? b). It unwraps an optional a and returns it if it contains a value, or returns a default value b if a is nil.

Example 7: Optional handling using nil-coalescing operator

 var someValue:Int! let defaultValue = 5 let unwrappedValue:Int = someValue ?? defaultValue print(unwrappedValue) 

When you run the program, the output will be:

 5

W powyższym programie zmienna someValue jest zdefiniowana jako opcjonalna i zawiera wartość zerową. Operator łączenia zerowego nie może rozpakować opcjonalnego, dlatego zwraca wartość defaultValue. Dlatego instrukcja print(unwrappedValue)zwraca 5 w konsoli.

 var someValue:Int? = 10 let defaultValue = 5 let unwrappedValue:Int = someValue ?? defaultValue print(unwrappedValue) 

Po uruchomieniu programu wynik będzie następujący:

 10

Jednak w powyższym programie opcjonalna zmienna someValue jest inicjowana wartością 10. Zatem operator łączący nil pomyślnie rozpakowuje wartość z someValue. Dlatego instrukcja someValue ?? defaultValuezwraca 10, a instrukcja zwraca print(unwrappedValue)10 w konsoli.

Interesujące artykuły...