"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.