unwrap example if-statement swift optional

if-statement - example - swift guard vs if



Usar mĂșltiples let-as dentro de un enunciado if en Swift (3)

Estoy desenvuelto dos valores de un diccionario y antes de usarlos tengo que lanzarlos y probar el tipo correcto. Esto es lo que se me ocurrió:

var latitude : AnyObject! = imageDictionary["latitude"] var longitude : AnyObject! = imageDictionary["longitude"] if let latitudeDouble = latitude as? Double { if let longitudeDouble = longitude as? Double { // do stuff here } }

Pero me gustaría empacar las dos si las consultas se convierten en una. Para que sea algo como eso:

if let latitudeDouble = latitude as? Double, longitudeDouble = longitude as? Double { // do stuff here }

Esa sintaxis no funciona, así que me preguntaba si había una forma hermosa de hacerlo.


Con Swift 3, puede usar un encadenamiento opcional, una declaración de cambio o un patrón opcional para resolver su problema.

1. Usando if let (enlace opcional / encadenamiento opcional)

El lenguaje de programación Swift establece sobre el encadenamiento opcional:

Varias consultas se pueden encadenar juntas, y toda la cadena falla correctamente si algún enlace en la cadena es nulo.

Por lo tanto, en el caso más simple, puede usar el siguiente patrón para usar múltiples consultas en su operación de encadenamiento opcional:

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?] let latitude = dict["latitude"] let longitude = dict["longitude"] if let latitude = latitude as? Double, let longitude = longitude as? Double { print(latitude, longitude) } // prints: 2.0 10.0

2. Usar tuplas y vinculación de valores en una declaración de cambio

Como alternativa a un encadenamiento opcional simple, la instrucción switch puede ofrecer una solución de grano fino cuando se usa con tuplas y enlace de valor:

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?] let latitude = dict["latitude"] let longitude = dict["longitude"] switch (latitude, longitude) { case let (Optional.some(latitude as Double), Optional.some(longitude as Double)): print(latitude, longitude) default: break } // prints: 2.0 10.0

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?] let latitude = dict["latitude"] let longitude = dict["longitude"] switch (latitude, longitude) { case let (latitude as Double, longitude as Double): print(latitude, longitude) default: break } // prints: 2.0 10.0

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?] let latitude = dict["latitude"] let longitude = dict["longitude"] switch (latitude as? Double, longitude as? Double) { case let (.some(latitude), .some(longitude)): print(latitude, longitude) default: break } // prints: 2.0 10.0

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?] let latitude = dict["latitude"] let longitude = dict["longitude"] switch (latitude as? Double, longitude as? Double) { case let (latitude?, longitude?): print(latitude, longitude) default: break } // prints: 2.0 10.0

3. Usando tuplas con if case (patrón opcional)

if case ( patrón opcional ) proporciona una forma conveniente de desenvolver los valores de la enumeración opcional. Puede usarlo con tuplas para realizar un encadenamiento opcional con múltiples consultas:

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?] let latitude = dict["latitude"] let longitude = dict["longitude"] if case let (.some(latitude as Double), .some(longitude as Double)) = (latitude, longitude) { print(latitude, longitude) } // prints: 2.0 10.0

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?] let latitude = dict["latitude"] let longitude = dict["longitude"] if case let (latitude as Double, longitude as Double) = (latitude, longitude) { print(latitude, longitude) } // prints: 2.0 10.0

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?] let latitude = dict["latitude"] let longitude = dict["longitude"] if case let (.some(latitude), .some(longitude)) = (latitude as? Double, longitude as? Double) { print(latitude, longitude) } // prints: 2.0 10.0

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?] let latitude = dict["latitude"] let longitude = dict["longitude"] if case let (latitude?, longitude?) = (latitude as? Double, longitude as? Double) { print(latitude, longitude) } // prints: 2.0 10.0


Swift 3.0

if let latitudeDouble = latitude as? Double, let longitudeDouble = longitude as? Double { // do stuff here }


Actualización para Swift 3:

Lo siguiente funcionará en Swift 3:

if let latitudeDouble = latitude as? Double, let longitudeDouble = longitude as? Double { // latitudeDouble and longitudeDouble are non-optional in here }

Solo asegúrese de recordar que si falla uno de los intentos de enlaces opcionales, el código dentro del bloque if-let no se ejecutará.

Nota: las cláusulas no tienen que ser necesariamente cláusulas ''let'', puede tener cualquier serie de verificaciones booleanas separadas por comas.

Por ejemplo:

if let latitudeDouble = latitude as? Double, importantThing == true { // latitudeDouble is non-optional in here and importantThing is true }

Swift 1.2:

Apple puede haber leído su pregunta, porque su código esperado se compila correctamente en Swift 1.2 (en beta hoy):

if let latitudeDouble = latitude as? Double, longitudeDouble = longitude as? Double { // do stuff here }

Swift 1.1 y anteriores:

Aquí están las buenas noticias: puedes hacer esto por completo. Una instrucción de conmutación en una tupla de sus dos valores puede usar la coincidencia de patrones para enviarlos a Double al mismo tiempo:

var latitude: Any! = imageDictionary["latitude"] var longitude: Any! = imageDictionary["longitude"] switch (latitude, longitude) { case let (lat as Double, long as Double): println("lat: /(lat), long: /(long)") default: println("Couldn''t understand latitude or longitude as Double") }

Actualización: esta versión del código ahora funciona correctamente.