Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Palavra-chave Guard em Swift

Durante o curso de Swift 4.2, é muito utilizado o "guard let" antes de declarar uma variável para tratar variáveis opcionais (Há várias ocasiões da utilização, mas na aula 5, vídeo 2 foi aonde eu resolvi perguntar).

Nos cursos de swift anteriores, foi visto e explicado o "if let", mas nesse eu não vi a explicação do uso do "guard let".

Por isso, gostaria de saber qual a diferença do "guard let" para o "if let".

Grato.

4 respostas

existem algumas diferenças entre if let e guard let. entre elas:

  • quando um "if let" dentro de uma função falha, qualquer código escrito fora das chaves desse if continuara a ser executado. Ex:
func printarNomeDoAluno() {

    if let nome = aluno.nome {
        print(nome)
    }
    print("final da função")
}

no exemplo acima, mesmo que o "if let" falhe, a linha: "print("final da função")" será executada

  • quando se usa um "guard let" seguido de "else { return }" caso esse guard falhe, a função para ali e todo código que vem a seguir não é executado. Ex:
func printarNomeDoAluno() {

    guard let nome = aluno.nome else { return }
    print(nome)
    print("final da função")
}

no exemplo acima caso o "guard let" falhe o programa não executara a linha: "print("final da função")"

  • Caso vc queira desembrulhar varias variáveis antes de executar um trecho de código, o "guard let" fica mais legível do que uma sequencia de "if let" um dentro do outro. Ex:
func printarInformacoesDoAluno() {

    if let nome = aluno.nome {
        if let nota = aluno.nota {
            if let endereco = aluno.endereco {
                print(nome)
                print(nota)
                print(endereco)
            }
        }
    }
}

o trecho acima fica difícil de ler

func printarInformacoesDoAluno() {

    guard let nome = aluno.nome else { return }
    guard let nota = aluno.nota else { return }
    guard let endereco = aluno.endereco else { return }

    print(nome)
    print(nota)
    print(endereco)

}

usando "guard let" a leitura fica bem mais agradável.

Qualquer duvida na explicação pode perguntar novamente.

Espero ter ajudado, bons estudos!

Certo, entendi o motivo de utilizar o "guard let" para interromper execução de código e melhorar a legibilidade, isso realmente é bastante útil.

O problema, é que você pode fazer a mesma coisa usando o "if let else", já que você usou o "guard let" com o "else", não?

Usando o exemplo que você deu:

func printarInformacoesDoAluno() {

    guard let nome = aluno.nome else { return }
    guard let nota = aluno.nota else { return }
    guard let endereco = aluno.endereco else { return }

    print(nome)
    print(nota)
    print(endereco)

}

Não possui o mesmo efeito que o seguinte código?

func printarInformacoesDoAluno() {

    if let nome = aluno.nome else { return }
    if let nota = aluno.nota else { return }
    if let endereco = aluno.endereco else { return }

    print(nome)
    print(nota)
    print(endereco)

}

Grato pela resposta.

solução!

"O problema, é que você pode fazer a mesma coisa usando o "if let else", já que você usou o "guard let" com o "else", não?"

Não. Vou explicar...

Quando usamos guard let, a constante criada possui o mesmo escopo de onde a instrução guard foi chamada. Veja o seu código:

func printarInformacoesDoAluno() {

    guard let nome = aluno.nome else { return }
    guard let nota = aluno.nota else { return }
    guard let endereco = aluno.endereco else { return }

    print(nome)
    print(nota)
    print(endereco)
}

Perceba que print(nome) está no mesmo nível do guard let e usa a constante nome que foi definida pelo guard let. Isso só funciona pois a constante definida é visível no mesmo nível do guard (em outras palavras, possui o mesmo escopo do guard).

Agora, vamos ao mesmo exemplo com if let:

func printarInformacoesDoAluno() {

    if let nome = aluno.nome else { return }
    if let nota = aluno.nota else { return }
    if let endereco = aluno.endereco else { return }

    print(nome)
    print(nota)
    print(endereco)

}

Esse código não compila.

As constantes definidas no if let são visíveis somente dentro do bloco do if let. Então ao chamar esse print(nome) fora do if let o compilador acusa um erro de Unresolved identifier (a variável nome não existe neste escopo).

Conclusão

Como o guard let cria constantes com o mesmo escopo de onde ele foi chamado, não é necessário fazer o encadeamento de chamadas quando queremos fazer validações, por exemplo. Então, essa acaba sendo uma das suas principais utilizações, em vez do if let.

Entendi perfeitamente, agora. Obrigado Felipe!