La garde peut améliorer la clarté
Lorsque vous utilisez guard, vous espérez beaucoup plus que le guard réussisse et il est quelque peu important que s'il ne réussit pas, vous souhaitiez simplement quitter la portée plus tôt . Comme vous vous gardez de voir si un fichier / image existe, si un tableau est vide ou non.
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
}
Si vous écrivez le code ci-dessus avec if-let, cela indique au développeur de lecture qu'il s'agit plus d'un 50-50. Mais si vous utilisez guard, vous ajoutez de la clarté à votre code et cela implique que je m'attends à ce que cela fonctionne 95% du temps ... si cela échouait, je ne sais pas pourquoi; c'est très peu probable ... mais utilisez simplement cette image par défaut à la place ou peut-être simplement affirmer avec un message significatif décrivant ce qui n'a pas fonctionné!
Évitez les guard
effets secondaires lorsqu'ils créent des effets secondaires, les protecteurs doivent être utilisés comme flux naturel . Évitez les gardes lorsque les else
clauses introduisent des effets secondaires. Les gardiens établissent les conditions requises pour que le code s'exécute correctement, offrant une sortie anticipée
Lorsque vous effectuez un calcul significatif dans la branche positive, refactoriser de if
à une guard
instruction et retourne la valeur de secours dans la else
clause
De: Le livre Swift Style d'Erica Sadun
De plus, en raison des suggestions ci-dessus et du code propre, il est plus probable que vous souhaitiez / devrez ajouter des assertions dans failed déclarations de garde , cela améliore simplement la lisibilité et indique clairement aux autres développeurs ce que vous attendiez.
guard let image = UIImage(named: selectedImageName) else { // YESSSSSS
assertionFailure("Missing \(selectedImageName) asset")
return
}
guard let image = UIImage(named: selectedImageName) else { // NOOOOOOO
return
}
De: le livre Swift Style d'Erica Sadun + quelques modifications
(vous n'utiliserez pas d'assertions / conditions préalables pour if-let
s. Cela ne semble tout simplement pas correct)
L'utilisation de gardes vous aide également à améliorer la clarté en évitant la pyramide de malheur. Voir la réponse de Nitin .
Guard crée un nouvelle variable
Il y a une différence importante que je pense que personne n'a bien expliqué.
Les deux guard let
etif let
dérouler la variable cependant
Avec guard let
vous créez une nouvelle variable qui existera dehors de l' else
instruction.
Avec if let
vous ne créez pas de nouvelle variable - après l'instruction else, vous n'entrez le bloc de code que si l'option facultative n'est pas nulle. La variable nouvellement créée n'existe qu'à l' intérieur du bloc de code pas après!
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)
}
}
Pour plus d'informations, if let
voir: Pourquoi la redéclaration de liaison facultative ne crée pas d'erreur
La garde exige sortie de la lunette
(Également mentionné dans la réponse de Rob Napier):
Vous DEVEZ avoir guard
défini à l' intérieur d' une fonction. Son objectif principal est d'abandonner / de renvoyer / de quitter la portée, si une condition n'est pas remplie:
var str : String?
guard let blogName1 = str else {
print("some error")
return // Error: Return invalid outside of a func
}
print (blogName1)
Car if let
vous n'avez pas besoin de l'avoir dans une fonction:
var str : String?
if let blogName1 = str {
print(blogName1) // You don't get any errors!
}
guard
contre if
Il convient de noter qu'il est plus approprié de voir cette question comme guard let
vs if let
et guard
vsif
.
Un standalone if
ne fait aucun déballage, pas plus qu'un standalone guard
. Voir l'exemple ci-dessous. Il ne se termine pas tôt si une valeur est nil
. Il n'y a AUCUNE valeur facultative. Il sort juste tôt si une condition n'est pas remplie.
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
lorsque lenon-nil
cas est valide. À utiliserguard
lorsque lenil
cas représente une sorte d'erreur.