No busques más por todo internet porque has llegado al sitio indicado, contamos con la solución que quieres sin liarte.
Solución:
if let
y guard let
sirven para propósitos similares, pero distintos.
El caso “else” de guard
debe salir del ámbito actual. Generalmente eso significa que debe llamar return
o abortar el programa. guard
se utiliza para proporcionar un retorno anticipado sin necesidad de anidar el resto de la función.
if let
anida su alcance y no requiere nada especial de él. Puede return
o no.
En general, si el if-let
bloque iba a ser el resto de la función, o su else
la cláusula tendría un return
o abortar en él, entonces deberías usar guard
en lugar de. Esto a menudo significa (al menos en mi experiencia), en caso de duda, guard
suele ser la mejor respuesta. Pero hay muchas situaciones en las que if let
todavía es apropiado.
Guardia puede mejorar claridad
Cuando usas la guardia tienes mucho más alto expectativa de que el guardia triunfar y es algo importante que si no tiene éxito, solo desee salir del alcance temprano. Al igual que usted guarda para ver si existe un archivo / imagen, si un array Está vacío 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, le transmite al desarrollador de lectura que es más un 50-50. Pero si usas guardia, agregas claridad a su código e implica que espero que esto funcione el 95% del tiempo … si alguna vez falla, no sé por qué; es muy improbable … pero luego use esta imagen predeterminada en su lugar o tal vez simplemente haga una afirmación con un mensaje significativo que describa lo que salió mal.
Evitar
guard
s cuando crean efectos secundarios, los protectores deben usarse como natural fluir. Evite los guardias cuandoelse
las cláusulas introducen efectos secundarios. Los guardias establecen requerido condiciones para que el código se ejecute correctamente, ofreciendo una salida anticipadaCuando realiza un cálculo significativo en la rama positiva, refactorice desde
if
a unguard
declaración y devuelve el valor de reserva en elelse
cláusulaDe: Libro Swift Style de Erica Sadun
Además, como resultado de las sugerencias anteriores y el código limpio, es más probable querrás / necesitarás agregar aserciones en fallido guard, simplemente mejora la legibilidad y deja claro a otros desarrolladores lo que esperabas.
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 protectores también le ayuda a mejorar la claridad al evitando la pirámide de perdición. Vea la respuesta de Nitin.
Guardia crea un nuevo variable
Hay una diferencia importante que creo que nadie ha explicado bien.
Ambos guard let
y if let
desenvolver la variable sin embargo
Con guard let
usted están creando una nueva variable que existe afuera de else
declaración.
Con if let
usted no están creando cualquier nueva variable: después de la instrucción else, solo ingresar el bloque de código si el opcional no es nulo. La variable recién creada solo existe dentro el 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 sobre if let
ver: Por qué la redeclaración del enlace opcional no crea un error
Guardia requiere alcance saliendo
(También mencionado en la respuesta de Rob Napier):
Debes tener guard
definido dentro una func. Su propósito principal es abortar / regresar / 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
no es necesario 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 ver esta pregunta como guard let
vs if let
y guard
vs if
.
Un independiente if
no desenvuelve, tampoco lo hace un independiente guard
. Vea el 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]
Cuándo usar if-let
y cuando usar guard
A menudo es una cuestión de estilo.
Di que tienes func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
y un opcional array de elementosvar optionalArray: [SomeType]?
), y debe devolver 0
Si el array es nil
(no establecido) o el count
Si el array tiene un valor (está establecido).
Podrías implementarlo así usando if-let
:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
if let array = optionalArray
return array.count
return 0
o así usando guard
:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
guard let array = optionalArray else
return 0
return array.count
Los ejemplos son funcionalmente idénticos.
Dónde guard
realmente brilla cuando tienes una tarea como validar datos y quieres que la función falle antes si algo está mal.
En lugar de anidar un montón de if-let
s a medida que se acerca a la finalización de la validación, la "ruta de éxito" y los opcionales ahora enlazados con éxito están todos en el alcance principal del método, porque las rutas de falla ya han regresado.
Te invitamos a añadir valor a nuestra información dando tu veteranía en las acotaciones.