Guardia puede mejorar la claridad
Cuando usa guardia, tiene una expectativa mucho mayor de que el guardia tenga éxito y es algo importante que si no tiene éxito, entonces solo desea salir del alcance antes de tiempo . Al igual que guarda para ver si existe un archivo / imagen, si una matriz está vacía o no.
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 escribe el código anterior con if-let, transmite al desarrollador de lectura que es más de un 50-50. Pero si usa guardia, agrega claridad a su código e implica que espero que funcione el 95% del tiempo ... si alguna vez falla, no sé por qué lo haría; es muy poco probable ... ¡pero simplemente use esta imagen predeterminada en su lugar o tal vez simplemente afirme con un mensaje significativo que describa lo que salió mal!
Evite guard
cuando crean efectos secundarios, los guardias deben usarse como un flujo natural . Evite los guardias cuando las else
cláusulas introducen efectos secundarios. Los guardias establecen las condiciones requeridas para que el código se ejecute correctamente, ofreciendo una salida anticipada
Cuando realiza un cálculo significativo en la rama positiva, refactorice if
a una guard
instrucción y devuelva el valor de reserva en la else
cláusula
Del libro de estilo rápido de Erica Sadun
Además, como resultado de las sugerencias anteriores y el código limpio, es más probable que desee / necesite agregar aserciones en las declaraciones de protección fallidas , solo mejora la legibilidad y deja en claro a otros desarrolladores lo que esperaba.
guard let image = UIImage(named: selectedImageName) else { // YESSSSSS
assertionFailure("Missing \(selectedImageName) asset")
return
}
guard let image = UIImage(named: selectedImageName) else { // NOOOOOOO
return
}
De: Libro Swift Style de Erica Sadun + algunas modificaciones
(no utilizará afirmaciones / condiciones previas para if-let
s. Simplemente no parece correcto)
El uso de guardias también te ayuda a mejorar la claridad al evitar la pirámide de la fatalidad. Ver la respuesta de Nitin .
Guard crea una nueva variable
Hay una diferencia importante que creo que nadie ha explicado bien.
Tanto guard let
y if let
Separar la variable embargo
Con guard let
usted está creando una nueva variable que existirá fuera de la else
declaración.
Si if let
no está creando ninguna variable nueva, después de la instrucción else, solo ingresa el bloque de código si el opcional no es nulo. ¡La variable recién creada existe solo dentro del bloque de código, no despué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)
}
}
Para obtener más información if let
, consulte: ¿Por qué la redeclaración de enlace opcional no crea un error?
Guardia requiere alcance salir
(También mencionado en la respuesta de Rob Napier):
DEBE haber guard
definido dentro de una función. Su propósito principal es abortar / devolver / salir del alcance, si no se cumple una condición:
var str : String?
guard let blogName1 = str else {
print("some error")
return // Error: Return invalid outside of a func
}
print (blogName1)
Para if let
que no necesite tenerlo dentro de ninguna función:
var str : String?
if let blogName1 = str {
print(blogName1) // You don't get any errors!
}
guard
vs if
Vale la pena señalar que es más apropiado para ver esta cuestión como guard let
vs if let
y guard
vs if
.
Un independiente if
no hace ningún desenvolvimiento, tampoco lo hace un independiente guard
. Ver ejemplo a continuación. No sale temprano si un valor es nil
. NO hay valores opcionales. Simplemente sale temprano si no se cumple una condición.
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
cuando elnon-nil
caso sea válido. Úseloguard
cuando elnil
caso representa algún tipo de error.