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!