Swift optionals
Quem migrou do Objective-C sem dúvidas tomou uma porradinha quando a Apple introduziu o Swift. Não por conta da dificuldade da linguagem, mas sim por conter sintaxes e conceitos diferentes. Um desses aprendizados novos pode ter sido com os “Optionals”
Optional: Uma variável de qualquer tipo que pode ser nil, sendo verificado como sucesso ou falha.
var number: Int? = nil
print("\(number)") // nil
number = 10
print("\(number)") // Optional(10)
print("\(number!)") // 10
No caso acima, a exclamação significa que o valor opcional será desembrulhado. Mas lembre-se, caso o valor com ’!’ seja nil, o app irá dar crash!
É claro que isso foi pensado e tem algumas formas de resolver e tratar. Abaixo, vamos ver um exemplo com guard e outro com if let.
guard ..
O guard declara uma variável de valor fixo de acordo com uma variável opcional para ser usado no código abaixo dele dentro do próprio escopo. Caso o optional seja unwrapped, o código continua sendo executado, caso contrário cairá no else do guard.
class GuardExample {
private var optional: String? = nil
private var str: String = "Normal String"
func canValidate () -> Bool {
// Variável 'string' pode ser usado abaixo deste bloco se 'optional' for != nil
// Caso seja nil, cairá no else e retorna 'false'
guard let string = optional else {
return false
}
print("The string is unwrapped! \(string)")
print("The optional wrapped \(optional)")
return true
}
}
let guardExample = GuardExample()
guardExample.canValidate() // false
if let ..
O if let declara uma variável para ser usado somente dentro do escopo aberto, como abaixo.
class IfLetExample {
private let optional: String? = nil
private var anotherOpt: String? = nil
private var str: String = "Normal String"
func canValidate () -> Bool {
// Variável 'string' poderá ser usada do mesmo jeito que o 'guard', porém apenas dentro do escopo do 'if'
if let string = optional {
// O mesmo se aplica aqui para o 'anotherString'
if let anotherString = anotherOpt {
// ... E assim vai
return true
}
}
// A variável não existe neste escopo
//print("The string is unwrapped! \(string)")
return true
}
}
let example = IfLetExample()
example.canValidate() // false
Não diria que tem forma melhor ou pior para dar unwrap nos opcionais, mas sim situações de melhor caso de uso. O Swift chama muito a minha atenção por ser muito bem tipada e simples de ler/escrever.
Sendo uma linguagem orientada à objetos, não tem como fugir de certos conceitos, mas dá para brincar bastante com programação funcional e até criar sua própria estrutura, mesmo que a boa prática fuja do contexto.
No futuro farei posts falando sobre infix operators, pois acho uma das maiores inovações da linguagem.
Referências
Gosto muito da documentação própria da apple e do blog do Ray Wenderlich para dúvidas e aprendizado em iOS. Claro que também é ótimo olhar como as libs são escritas, como por exemplo o Gloss que escreveu um infix operator bem peculiar.
Fico por aqui. Um abraço!