Swift Optionals: Πώς να τα χρησιμοποιήσετε (με παραδείγματα)

Σε αυτό το άρθρο, θα μάθετε για προαιρετικά, τις περιπτώσεις χρήσης και τον προαιρετικό χειρισμό στο Swift.

Στο προηγούμενο άρθρο, μάθαμε για διαφορετικούς τύπους δεδομένων που διατίθενται στο Swift και επίσης παρατηρήσαμε ότι η μεταβλητή ή η σταθερά που δηλώνεται από αυτούς τους τύπους περιέχει μια προεπιλεγμένη τιμή.

Παράδειγμα:

 αφήστε someValue = Int () εκτύπωση (someValue) 

Όταν εκτελείτε το πρόγραμμα, η έξοδος θα είναι:

 0

Ωστόσο, υπάρχει ένας άλλος τύπος δεδομένων στο Swift που ονομάζεται Optional, του οποίου η προεπιλεγμένη τιμή είναι μια τιμή null ( nil). Μπορείτε να χρησιμοποιήσετε προαιρετικό όταν θέλετε μια μεταβλητή ή μια σταθερά να μην περιέχει καμία τιμή. Ένας προαιρετικός τύπος μπορεί να περιέχει μια τιμή ή να λείπει μια τιμή (μηδενική τιμή).

Μη τεχνικά, μπορείτε να σκεφτείτε προαιρετικά ως κουτί παπουτσιών. Το κουτί παπουτσιών μπορεί να περιέχει ή να μην περιέχει παπούτσι. Λοιπόν, πρέπει να γνωρίζετε εκ των προτέρων, ενώ έχετε πρόσβαση στο παπούτσι από το κουτί.

Πώς να δηλώσετε προαιρετικό;

Μπορείτε απλά να αντιπροσωπεύσετε έναν τύπο δεδομένων ως προαιρετικό προσαρτώντας !ή ?στο Type. Εάν ένα προαιρετικό περιέχει μια τιμή, επιστρέφει την τιμή ως Optional, αν όχι επιστρέφει nil.

Παράδειγμα 1: Πώς να δηλώσετε ένα προαιρετικό στο Swift;

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

Όταν εκτελείτε το πρόγραμμα, η έξοδος θα είναι:

 μηδέν μηδέν

Στο παραπάνω πρόγραμμα, έχουμε αρχικοποιήσει έναν προαιρετικό τύπο χρησιμοποιώντας ?και !. Και οι δύο τρόποι είναι έγκυροι για τη δημιουργία ενός προαιρετικού αλλά υπάρχει μια σημαντική διαφορά την οποία θα διερευνήσουμε παρακάτω.

Η δήλωση προαιρετικού Int σημαίνει ότι η μεταβλητή θα έχει ακέραια τιμή ή καμία τιμή. Δεδομένου ότι δεν έχει αντιστοιχιστεί καμία τιμή στη μεταβλητή, μπορείτε να δείτε και τις δύο printεξόδους δήλωσης nilστην οθόνη.

Παράδειγμα 2: Αντιστοίχιση και πρόσβαση σε μια τιμή από μια προαιρετική

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

Όταν εκτελείτε το πρόγραμμα, η έξοδος θα είναι:

 Προαιρετικό (5) 5 

Στο παραπάνω πρόγραμμα, έχουμε δηλώσει προαιρετικό Intτύπο και εκχωρήσαμε την τιμή 5 σε αυτό.

Όπως μπορείτε να δείτε, η εκτύπωση του προαιρετικού print(someValue)δεν σας δίνει 5αλλά Optional(5). Είναι της μορφή όπως περιγράφεται παραπάνω: Optional. Για να αποκτήσουμε πρόσβαση σε αυτό, χρειαζόμαστε έναν μηχανισμό που ονομάζεται αποσυσκευασία .

Μπορείτε να ξετυλίξετε ένα προαιρετικό προσαρτώντας !χαρακτήρα στο τέλος της μεταβλητής / σταθερά όπως στην επόμενη γραμμή print(someValue!). print(someValue!)ξετυλίγει το προαιρετικό και εξέρχεται 5στην οθόνη.

Ωστόσο, να θυμάστε, αυτό το είδος μηχανισμού αποσυμπίεσης θα πρέπει να χρησιμοποιείται μόνο όταν είστε βέβαιοι ότι το προαιρετικό θα έχει σίγουρα μια τιμή όταν θα έχετε πρόσβαση σε αυτό.

Παράδειγμα 3: Δηλώνει ρητά ένα μη τυλιγμένο προαιρετικό

Μπορείτε επίσης να δημιουργήσετε ένα μη τυλιγμένο προαιρετικό όπως:

 let someValue:Int! = 5 print(someValue) 

Όταν εκτελείτε το πρόγραμμα, η έξοδος θα είναι:

 5

Στο παραπάνω πρόγραμμα, Int!δημιουργεί ένα μη τυλιγμένο προαιρετικό, το οποίο ξετυλίγει αυτόματα την τιμή ενώ την έχετε πρόσβαση, έτσι ώστε να μην χρειάζεται να προσθέτετε κάθε φορά τον !χαρακτήρα.

Να είστε βέβαιοι ενώ χρησιμοποιείτε τέτοιου είδους προαιρετικά, η μεταβλητή θα πρέπει πάντα να έχει μια τιμή όταν έχετε πρόσβαση σε αυτήν. Εάν δεν το κάνετε, θα λάβετε ένα μοιραίο σφάλμα σφάλματος.

Παράδειγμα 4: Θανατηφόρο σφάλμα κατά την πρόσβαση σε μηδενική συσκευασία προαιρετική

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

Όταν εκτελείτε το πρόγραμμα, θα λάβετε ένα σφάλμα ως μοιραίο σφάλμα: βρέθηκε απροσδόκητα μηδέν κατά την αποσυσκευασία μιας προαιρετικής τιμής, επειδή ο κώδικας unwrappedValue:Int = someValueπροσπαθεί να αντιστοιχίσει τιμή από το προαιρετικό someValue σε μεταβλητή unsrappedValue.

Ωστόσο, το somevalue είναι ένας Optionalτύπος που περιέχει nilτιμή. Η προσπάθεια εκχώρησης μηδενικής τιμής σε μεταβλητή τιμή που δεν είναι προαιρετική θα οδηγήσει σε σφάλμα.

Υπάρχουν διαφορετικές τεχνικές για την αντιμετώπιση αυτής της υπόθεσης που εξηγούνται παρακάτω.

Προαιρετικός χειρισμός

Για να χρησιμοποιήσετε την τιμή ενός προαιρετικού, πρέπει να είναι ξετυλιγμένο. Ο καλύτερος τρόπος για να χρησιμοποιήσετε την προαιρετική τιμή είναι με αποσυναρμολόγηση υπό όρους και όχι με την αναγκαστική αποσυσκευασία χρησιμοποιώντας τον !χειριστή.

Αυτό συμβαίνει επειδή η υπό όρους αποσυσκευασία ρωτά Ελέγξτε εάν αυτή η μεταβλητή έχει τιμή; . Εάν ναι, δώστε την τιμή, αλλιώς θα χειριστεί τη μηδενική θήκη.

Αντίθετα, η δύναμη ξετυλίγματος αναφέρει ότι Αυτή η μεταβλητή έχει μια τιμή ενώ τη χρησιμοποιείτε . Επομένως, όταν αναγκάζετε να ξετυλίξετε μια μεταβλητή που είναι μηδενική, το πρόγραμμά σας θα ρίξει ένα μη αναμενόμενο μηδέν που βρέθηκε ενώ ξετυλίγοντας μια προαιρετική εξαίρεση και σφάλμα . Μερικές από τις τεχνικές για την απεμπλοκή υπό όρους εξηγούνται παρακάτω:

1. Δήλωση if

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

Στο παραπάνω πρόγραμμα, η μεταβλητή someValue ορίζεται προαιρετική και περιέχει μηδενική τιμή. Ο τελεστής μηδενικής συγχώνευσης αποτυγχάνει να ξετυλίξει το προαιρετικό, επομένως επιστρέφει την defaultValue. Επομένως, η δήλωση print(unwrappedValue)εξάγει 5 στην κονσόλα.

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

Όταν εκτελείτε το πρόγραμμα, η έξοδος θα είναι:

 10

Ωστόσο, στο παραπάνω πρόγραμμα, η προαιρετική μεταβλητή someValue αρχικοποιείται με την τιμή 10. Επομένως, ο τελεστής μηδενικής συγχώνευσης ξετυλίγει με επιτυχία την τιμή από someValue. Επομένως, η δήλωση someValue ?? defaultValueεπιστρέφει 10 και η δήλωση print(unwrappedValue)εξέρχεται 10 στην κονσόλα.

ενδιαφέροντα άρθρα...