Wache kann Klarheit verbessern
Wenn Sie Guard verwenden, haben Sie eine viel höhere Erwartung, dass der Guard erfolgreich ist, und es ist etwas wichtig, dass Sie den Bereich nur vorzeitig verlassen möchten, wenn er nicht erfolgreich ist . Wie Sie schützen, um zu sehen, ob eine Datei / ein Bild vorhanden ist, ob ein Array leer ist oder nicht.
func icon() -> UIImage {
guard let image = UIImage(named: "Photo") else {
return UIImage(named: "Default")! //This is your fallback
}
return image //-----------------you're always expecting/hoping this to happen
}
Wenn Sie den obigen Code mit if-let schreiben, wird dem lesenden Entwickler mitgeteilt, dass es sich eher um eine 50-50 handelt. Aber wenn Sie Guard verwenden, fügen Sie Ihrem Code Klarheit hinzu , und dies impliziert, dass ich davon ausgehe, dass dies in 95% der Fälle funktioniert. Sollte dies jemals fehlschlagen, weiß ich nicht, warum dies der Fall ist. Es ist sehr unwahrscheinlich ... aber verwenden Sie stattdessen einfach dieses Standardbild oder bestätigen Sie mit einer aussagekräftigen Nachricht, was schief gelaufen ist!
Vermeiden Sie guard
s, wenn sie Nebenwirkungen verursachen, Schutzvorrichtungen sind als natürlicher Fluss zu verwenden. Vermeiden Sie Wachen, wenn else
Klauseln Nebenwirkungen hervorrufen. Die Wachen legen die erforderlichen Bedingungen für die ordnungsgemäße Ausführung des Codes fest und bieten einen vorzeitigen Ausstieg
Wenn Sie im positiven Zweig eine signifikante Berechnung durchführen, refaktorieren Sie von if
zu einer guard
Anweisung und geben den Fallback-Wert in der else
Klausel zurück
Aus: Erica Saduns Swift Style Buch
Aufgrund der obigen Vorschläge und des sauberen Codes ist es auch wahrscheinlicher, dass Sie Behauptungen zu fehlgeschlagenen Guard-Anweisungen hinzufügen möchten / müssen. Dies verbessert lediglich die Lesbarkeit und macht anderen Entwicklern klar, was Sie erwartet haben.
guard let image = UIImage(named: selectedImageName) else { // YESSSSSS
assertionFailure("Missing \(selectedImageName) asset")
return
}
guard let image = UIImage(named: selectedImageName) else { // NOOOOOOO
return
}
Aus: Erica Saduns Swift Style Buch + einige Modifikationen
(Sie werden keine Asserts / Voraussetzungen für if-let
s verwenden. Es scheint einfach nicht richtig zu sein)
Die Verwendung von Wachen hilft Ihnen auch dabei, die Klarheit zu verbessern, indem Sie die Pyramide des Untergangs vermeiden . Siehe Nitins Antwort .
Guard erstellt eine neue Variable
Es gibt einen wichtigen Unterschied, den meines Erachtens niemand gut erklärt hat.
Beides guard let
und if let
entpacken Sie die Variable jedoch
Mit guard let
Sie schaffen eine neue Variable, wird existieren außerhalb der else
Aussage.
Mit if let
Ihnen nicht zu schaffen sind , jeden neuer variabler nach der else - Anweisung, nur geben Sie den Code - Block , wenn die optionalen nicht-Null ist. Die neu erstellte Variable existiert nur innerhalb des Codeblocks, nicht danach!
guard let:
func someFunc(blog: String?) {
guard let blogName = blog else {
print("some ErrorMessage")
print(blogName) // will create an error Because blogName isn't defined yet
return
}
print(blogName) // You can access it here ie AFTER the guard statement!!
//And if I decided to do 'another' guard let with the same name ie 'blogName' then I would create an error!
guard let blogName = blog else { // errorLine: Definition Conflicts with previous value.
print(" Some errorMessage")
return
}
print(blogName)
}
if-let:
func someFunc(blog: String?) {
if let blogName1 = blog {
print(blogName1) // You can only access it inside the code block. Outside code block it doesn't exist!
}
if let blogName1 = blog { // No Error at this line! Because blogName only exists inside the code block ie {}
print(blogName1)
}
}
Weitere Informationen finden if let
Sie unter: Warum die erneute Deklaration der optionalen Bindung keinen Fehler verursacht
Guard erfordert das Verlassen des Oszilloskops
(Auch in Rob Napiers Antwort erwähnt):
Sie müssen innerhalb einer Funktion guard
definiert haben . Der Hauptzweck besteht darin, den Bereich abzubrechen / zurückzugeben / zu beenden, wenn eine Bedingung nicht erfüllt ist:
var str : String?
guard let blogName1 = str else {
print("some error")
return // Error: Return invalid outside of a func
}
print (blogName1)
Denn if let
Sie müssen es nicht in irgendeiner Funktion haben:
var str : String?
if let blogName1 = str {
print(blogName1) // You don't get any errors!
}
guard
vs. if
Es ist erwähnenswert, dass es angemessener ist, diese Frage als guard let
vs if let
und guard
vs zu betrachten if
.
Ein Standalone if
führt kein Auspacken durch, ein Standalone auch nicht guard
. Siehe Beispiel unten. Es wird nicht vorzeitig beendet, wenn ein Wert ist nil
. Es gibt KEINE optionalen Werte. Es wird nur vorzeitig beendet, wenn eine Bedingung nicht erfüllt ist.
let array = ["a", "b", "c"]
func subscript(at index: Int) -> String?{
guard index > 0, index < array.count else { return nil} // exit early with bad index
return array[index]
}
if let
wenn dernon-nil
Fall gültig ist. Verwenden Sie diese Option,guard
wenn dernil
Fall einen Fehler darstellt.