Saltar al contenido

Swift: guardia let vs if let

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 guards cuando crean efectos secundarios, los protectores deben usarse como natural fluir. Evite los guardias cuando else las cláusulas introducen efectos secundarios. Los guardias establecen requerido condiciones para que el código se ejecute correctamente, ofreciendo una salida anticipada

  • Cuando realiza un cálculo significativo en la rama positiva, refactorice desde if a un guard declaración y devuelve el valor de reserva en el else cláusula

De: 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-lets. 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 letdesenvolver 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-lets 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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *