Lição 4: Falhas como parte do contrato
Uma falha de rede, uma conta desativada e um arquivo ausente são resultados possíveis do domínio. O tipo Result torna esses caminhos visíveis na assinatura, em vez de escondê-los numa exceção.
Objetivo
Em uma frase: retornar e propagar erros de forma explícita e escaneável.
Código
func buscarSaldo(conta: ref Conta): Result<int, str> {
if conta.ativa == false {
return Result.Err("conta desativada")
}
return Result.Ok(conta.saldo)
}
O tipo Result<int, str> diz que a função ou devolve um int (Result.Ok(...)) ou devolve uma mensagem de erro (Result.Err(...)). Nada de exceção escondida nos bastidores.
Propagando com ?
func resumo(conta: ref Conta): Result<str, str> {
let saldo = buscarSaldo(conta)?
return Result.Ok("Saldo: " + saldo)
}
O ? encurta a propagação: se der Err, a função inteira retorna esse erro; se der Ok, você extrai o valor.
Experimente
Remova o ? de buscarSaldo(conta) e veja o compilador pedir que você trate o Result explicitamente. Ele não deixa um erro escapar sem você decidir o que fazer.
Option<T> funciona do mesmo jeito: Option.Some(...) ou Option.None, sem null. Combine Option e Result para modelar “pode não existir” e “pode falhar” como coisas distintas.
Erros como valores mantêm o fluxo de erro visível no próprio código — você vê exatamente onde uma operação pode falhar e qual camada decide o que fazer.