← Swift EspañolChapter 09 of 13

Opcionales

## Objetivos de Aprendizaje - Comprender que son los opcionales - Usar tipos opcionales y desencapsulado - Dominar enlace opcional - Trabajar con fusion de nil ## Que son los Opcionales? Los opcionales representan valores que pueden o no existir: ```swift var nombre: String? = "Alicia" var vacio: String? = nil ``` ### Por Que Opcionales? ```swift // Sin opcionales - no queda claro si el valor puede estar ausente // String nombre = null; // Que significa null? // Con opcionales - explicito sobre valores ausentes let nombre: String? = nil ``` ## Declaracion de Tipo Opcional ### Sintaxis ```swift String? // Opcional String (puede contener String o nil) Int? // Opcional Int Double? // Opcional Double Bool? // Opcional Bool [String]? // Opcional Arreglo de Strings ``` ### No Opcional vs Opcional ```swift let cierto: String = "Hola" // Debe tener un valor let talvez: String? = nil // Puede o no tener valor ``` ## Desencapsulado Forzado ### Usando (!) ```swift let nombre: String? = "Alicia" print(nombre!) // "Alicia" // ADVERTENCIA: Crashea si es nil! let vacio: String? = nil // print(vacio!) // CRASH EN TIEMPO DE EJECUCION! ``` ### Cuando Evitar ```swift // MAL - crashea si es nil func obtenerNombreUsuario() -> String? { return nil } let nombreUsuario = obtenerNombreUsuario()! // print(nombreUsuario) // Crasheo! ``` ## Enlace Opcional ### if let ```swift let nombre: String? = "Alicia" if let nombreDesencapsulado = nombre { print("Hola, \(nombreDesencapsulado)") } else { print("No se proporciono nombre") } // Salida: Hola, Alicia ``` ### guard let ```swift func saludar(nombre: String?) { guard let nombre = nombre else { print("Sin nombre") return } print("Hola, \(nombre)") } saludar(nombre: "Alicia") // Hola, Alicia saludar(nombre: nil) // Sin nombre ``` ### Enlace Multiple ```swift let nombre: String? = "Alicia" let edad: Int? = 30 if let nombreDesencapsulado = nombre, let edadDesencapsulada = edad { print("\(nombreDesencapsulado) tiene \(edadDesencapsulada)") } // Puede combinar con condiciones if let nombre = nombre, let edad = edad, edad >= 18 { print("\(nombre) es adulto") } ``` ## Fusion de Nil ### Operador ?? ```swift let nombre: String? = nil let nombreMostrar = nombre ?? "Anonimo" print(nombreMostrar) // "Anonimo" let nombreReal: String? = "Alicia" let saludo = "Hola, \(nombreReal ?? "Invitado")" print(saludo) // "Hola, Alicia" ``` ### Encadenamiento ```swift let anidado: String?? = nil let resultado = anidado ?? "pordefecto" // "pordefecto" let cadenaOpcional: String? = "Hola" let resultado2 = cadenaOpcional ?? "nil o vacio" // "Hola" ``` ## Opcionales Desencapsulados Implicitamente ### Declaracion ```swift var opcionalImplicito: String! = "Hola" print(opcionalImplicito) // No necesita desencapsular ``` ### Casos de Uso ```swift class ControladorVista { var etiqueta: UILabel! // Se configurara despues func viewDidLoad() { etiqueta.text = "Hola" // Seguro porque sabemos que esta configurado } } ``` ### Peligros ```swift var peligroso: String! = nil print(peligroso) // CRASHO! ``` ## Encadenamiento Opcional ### Sintaxis de Encadenamiento Opcional ```swift let calle: String? = direccion?.ciudad?.calle?.nombre ``` ### Ejemplo ```swift class Persona { var residencia: Residencia? } class Residencia { var direccion: Direccion? } class Direccion { var calle: String = "123 Calle Principal" } let persona = Persona() let calle = persona.residencia?.direccion?.calle // calle es nil (residencia de persona es nil) // Sin crasheo - el encadenamiento se corta ``` ### Con Metodos ```swift if let cantidad = persona.residencia?.calcularCantidadHabitaciones?() { print("La casa tiene \(cantidad) habitaciones") } ``` ## Comparar Opcionales ### Igualdad ```swift let a: Int? = 5 let b: Int? = 5 let c: Int? = nil a == b // true a == c // false a == 5 // true (compara con no opcional) c == nil // true ``` ### Caso de Enum Opcional ```swift enum Color { case rojo, verde, azul } let seleccionado: Color? = .rojo if seleccionado == .rojo { print("Rojo esta seleccionado") } ``` ## Map y FlatMap ### Map Opcional ```swift let numero: Int? = 5 let alCuadrado = numero.map { $0 * $0 } // Optional(25) let numeroNil: Int? = nil let nilAlCuadrado = numeroNil.map { $0 * $0 } // nil ``` ### FlatMap Opcional ```swift let cadena: String? = "42" let entero = cadena.flatMap { Int($0) } // Optional(42) let invalida: String? = "hola" let noEntero = invalida.flatMap { Int($0) } // nil ``` ## Coincidencia de Patrones ### switch con Opcionales ```swift let valor: Int? = 5 switch valor { case nil: print("Es nil") case let desencriptado?: print("Tiene valor: \(desencriptado)") } ``` ### if case ```swift let edad: Int? = 25 if case let desencriptado? = edad { print("La edad es \(desencriptado)") } ``` ## Errores Comunes ### Nil Inesperado ```swift func obtenerUsuario() -> String? { return nil } let usuario = obtenerUsuario() // usuario.uppercased() // ERROR: No se puede llamar en Opcional // usuario!.uppercased() // CRASHO: valor nil ``` ### Tipo Incorrecto ```swift let cadena: String? = "123" // let numero: Int = cadena // ERROR: No se puede asignar String? a Int let numero: Int? = cadena.map { Int($0) } ``` ## Mejores Practicas ### Hacer ```swift // Usar enlace opcional if let valor = opcional { usar(valor) } // Usar guard para salida anticipada func procesar() { guard let valor = opcional else { return } usar(valor) } // Usar fusion de nil para valores por defecto let resultado = opcional ?? "pordefecto" ``` ### No Hacer ```swift // No forzar desencapsulado // let valor = opcional! // PELIGROSO // No comparar con nil explicitamente (preferir enlace opcional) // if opcional != nil { } // No es idiomatico ``` ## Resumen - Los opcionales representan valores que pueden ser nil - Declarar con sintaxis `Tipo?` - Desencapsulado forzado con `!` (peligroso si es nil) - Enlace opcional: `if let` y `guard let` - Fusion de nil: `??` proporciona valor por defecto - Encadenamiento opcional: `?.` accede propiedades de forma segura - `map` y `flatMap` transforman valores opcionales - Opcionales desencapsulados implicitamente (`Tipo!`) difieren el desencapsulado - Preferir desencapsulado seguro sobre forzado

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →