Kiedy używać strażników
Jeśli masz kontroler widoku z kilkoma elementami UITextField lub innym rodzajem danych wprowadzanych przez użytkownika, natychmiast zauważysz, że musisz rozpakować opcjonalny textField.text, aby dostać się do tekstu w środku (jeśli istnieje!). isEmpty nie zrobi tu nic dobrego, bez żadnego wpisu pole tekstowe po prostu zwróci zero.
Masz więc kilka z nich, które rozpakowujesz i ostatecznie przekazujesz do funkcji, która wysyła je do punktu końcowego serwera. Nie chcemy, aby kod serwera miał do czynienia z zerowymi wartościami lub przez pomyłkę wysyłał nieprawidłowe wartości do serwera, więc najpierw rozpakujemy te wartości wejściowe za pomocą wartownika.
func submit() {
guard let name = nameField.text else {
show("No name to submit")
return
}
guard let address = addressField.text else {
show("No address to submit")
return
}
guard let phone = phoneField.text else {
show("No phone to submit")
return
}
sendToServer(name, address: address, phone: phone)
}
func sendToServer(name: String, address: String, phone: String) {
...
}
Zauważysz, że nasza funkcja komunikacji z serwerem przyjmuje jako parametry nie opcjonalne wartości ciągu, dlatego przedtem rozpakuj straż. Rozpakowywanie jest trochę nieintuicyjne, ponieważ jesteśmy przyzwyczajeni do rozpakowywania, jeśli pozwala, które rozpakowuje wartości do użycia w bloku. W tym przypadku instrukcja guard ma powiązany blok, ale w rzeczywistości jest to blok inny - tzn. Czynność wykonywana w przypadku niepowodzenia rozpakowywania - wartości są rozpakowywane bezpośrednio w tym samym kontekście, co sama instrukcja.
// rozdzielenie obaw
Bez ochrony
Bez użycia straży otrzymalibyśmy wielki stos kodu, który przypomina piramidę zagłady . Nie skaluje się to dobrze do dodawania nowych pól do naszego formularza ani do tworzenia bardzo czytelnego kodu. Wcięcie może być trudne do naśladowania, szczególnie przy wielu innych stwierdzeniach przy każdym rozwidleniu.
func nonguardSubmit() {
if let name = nameField.text {
if let address = addressField.text {
if let phone = phoneField.text {
sendToServer(name, address: address, phone: phone)
} else {
show("no phone to submit")
}
} else {
show("no address to submit")
}
} else {
show("no name to submit")
}
}
Tak, moglibyśmy nawet połączyć je wszystkie, jeśli pozwolimy na instrukcje w jedną instrukcję oddzieloną przecinkami, ale stracilibyśmy możliwość stwierdzenia, która instrukcja się nie powiodła i przedstawienia użytkownikowi komunikatu.
https://thatthinginswift.com/guard-statement-swift/