Os opcionais utilízanse en situacións onde un valor pode estar ausente.
Un opcional representa dúas posibilidades:
- Existe un valor, e podes extraer o opcional para acceder a ese valor
- Non existe un valor en absoluto.
Vamos a ver como se poden empregar co seguinte exemplo: O tipo Int
de Swift ten un inicializador que tenta converter un valor String
nun valor Int
. Non todas as cadeas poden ser convertidas en enteiros:
- A cadea «123» pode converterse no valor numérico 123
- A cadea «Ola, mundo.» non ten un valor numérico no cal converterse.
Así, no seguinte exemplo tentamos converter un String nun Int:
let posibleNumero = "123"
let numeroConvertido = Int(posibleNumero)
//se infiere que numeroConvertido es de tipo "Int?", o "Int opcional"
Dado que o inicializador (liña 2) podería fallar, este devolve un Int opcional
, en lugar dun Int
.
Un Int opcional escríbese Int?
.
O signo de interrogación indica que o valor que contén é opcional, o que significa que pode conter algún valor Int
, ou pode non conter ningún valor en absoluto.
nil #
Para fixar unha variable opcional nun estado sen valor, asígnalle o valor especial nil
:
var codigoDeRespuestaDelServidor: Int? = 404
//codigoDeRespuestaDelServidor contiene un valor real Int de 404
codigoDeRespuestaDelServidor = nil
//codigoDeRespuestaDelServidor ahora no contiene valor
codigoDeRespuestaDelServidor = 505
//codigoDeRespuestaDelServidor ahora contén 505
Se defines unha variable opcional sen proporcionar un valor predeterminado, á variable asígnaselle nil
automaticamente:
var respuestaEncuesta: String?
// a respuestaEncuesta se le asigna nil automáticamente
Extraer/Desempqeutar o valor dun opcional #
En moitas ocasións, ao longo do noso programa, interésanos traballar co valor que contén o opcional. É dicir, desempaquetar o opcional e traballar unicamente co seu valor, xa que nos facilita e simplifica moito o código.
A continuación imos aprender a como extraer o valor dun opcional e vas ver que podemos facelo de diferentes maneiras:
Extraer valor con if-let
#
Neste exemplo, imos a transforma un String
a Int
, e imos usar if-let
para extraer o valor do opcional (en caso de ter un valor). Imos velo:
var cadea = "123" // 1
var numero = Int(cadea) // 2
if let numeroExtraido = numero { // 3
print(numeroExtraido) // 4
} else {
print("Non ten valor") // 5
}
- Creamos unha variable de tipo
String
co valor de"123"
- Transformamos
cadea
a unInt
. Para facelo, usamos o inicializadorInt()
ao que se lle pasa a cadea que queremos transformar a número. - O tipo da variable
numero
é opcional, éInt?
como aprendemos ao principio deste capítulo. Isto é debido a que esta transformación pode fallar (e se pode fallar entón pode conter nil, e por tanto é un opcional). - Creamos un
if-let
para extraer o valor da variablenumero
. Senumero
ten un valor, almacénase ennumeroExtraido
- Visualizamos o valor de
numeroExtraido
(neste caso é o número 123).- Como curiosidade, comentar que o tipo de
numeroExtraido
é de tipoInt
. - É dicir, podemos usar
numeroExtraido
como unha variable normal (sen tratala como un opcional).
- Como curiosidade, comentar que o tipo de
- Se non se pode extraer ningún valor de
numero
, visualizarmos por consola «Non ten valor».
Extraer valor con nil coalescing (??
) #
Podemos usar o operador ??
para obter un valor por defecto se o valor dun opcional que queremos usar é nil
.
Imaxina que queres asignar o valor dun opcional a unha variable, se usas o operador ??
comprobarase que se o valor do opcional é nil
, podemos darlle un valor por defecto á variable. Vese moi claro no seguinte exemplo:
var cadeaOpcional: String? = nil
var valorFinal = cadeaOpcional ?? "Drodicio"
print(valorFinal) // Visualiza Drodicio
cadeaOpcional = "Agora non son nil"
valorFinal = cadeaOpcional ?? "Drodicio"
print(valorFinal) // Visualiza "Agora non son nil"
Extraer valor coa función map
#
var cadea = "123" // 1
var numero = Int(cadea) // 2
numero.map { valor in
print("Valor \(valor)") // 3. Visualiza 123
}
Neste caso visualizamos unha mensaxe que aparecerá por consola coa cadea de texto «Valor » e xusto a continuación poñemos o valor que contén numero
.
- Este
print
mostrarase por consola só senumero
ten algún valor - En caso de ser
nil
oprint
domap
non se executa
Non te preocupes sobre algúns conceptos como if
, map
, … etc. Todo isto, abordarémolo máis adiante.
Forzar o desempaquetado de opcionais #
Swift permíteche sobreescribir a forma segura de traballar cos opcionais utilizando un signo de exclamación !
. Se sabes de xeito seguro que un opcional ten un valor (non é nil
), podes forzar o seu desempaquetado colocando un signo de exclamación logo de leste.
Ten moito coidado: Se fas isto sobre un opcional que é nil
, o teu código vai fallar.
func anoPublicaciónAlbum(nome: String) -> Int? {
if nome == "Taylor Swift" { return 2006 }
if nome == "Fearless" { return 2008 }
if nome == "Speak Now" { return 2010 }
if nome == "Red" { return 2012 }
if nome == "1989" { return 2014 }
return nil
}
var ano = anoPublicaciónAlbum(nome: "Red")
if ano == nil {
print("Hai un erro")
} else {
print("Foi publicado no ano \(ano!)")
}