Fácil Go
Erro sentinela e errors.Is
Enunciado
Crie uma função Dividir(a, b float64) (float64, error) que retorna um erro sentinela ErrDivisaoPorZero quando b for zero. No main, chame a função com b=0 e use errors.Is para verificar se o erro é ErrDivisaoPorZero, imprimindo uma mensagem adequada.
Requisitos
- Definir a variável
ErrDivisaoPorZerocomerrors.New. - A função
Dividirretorna(0, ErrDivisaoPorZero)quandob == 0. - No
main, usarerrors.Ispara checar o erro e imprimir"Erro: divisão por zero". - Imprimir o resultado da divisão quando não houver erro.
Código inicial
package main
import (
"errors"
"fmt"
)
// ErrDivisaoPorZero é o erro sentinela.
var ErrDivisaoPorZero = errors.New("divisão por zero")
func Dividir(a, b float64) (float64, error) {
// Implemente
return 0, nil
}
func main() {
// Chame Dividir com b=0 e trate o erro
}
Saída esperada
Erro: divisão por zero
Ver dica
Use errors.Is(err, ErrDivisaoPorZero) para comparar. Lembre-se de retornar o erro exato, não um novo.
Mostrar solução
package main
import (
"errors"
"fmt"
)
// ErrDivisaoPorZero é o erro sentinela para divisão por zero.
var ErrDivisaoPorZero = errors.New("divisão por zero")
// Dividir retorna a divisão de a por b, ou erro se b for zero.
func Dividir(a, b float64) (float64, error) {
if b == 0 {
return 0, ErrDivisaoPorZero // retorna o erro sentinela
}
return a / b, nil
}
func main() {
_, err := Dividir(10, 0)
if err != nil {
if errors.Is(err, ErrDivisaoPorZero) {
fmt.Println("Erro: divisão por zero")
}
}
}
Passo a passo
- Declaramos
ErrDivisaoPorZerocomo um erro sentinela usandoerrors.New. Isso cria um valor único que pode ser comparado depois. - A função
Dividirverifica seb == 0; se sim, retorna0e o erro sentinela. - No
main, chamamosDividir(10, 0)e capturamos o erro. - Usamos
errors.Is(err, ErrDivisaoPorZero)para verificar se o erro é exatamente o sentinela (ou o envolve). - Se for, imprimimos a mensagem
"Erro: divisão por zero".
Por que funciona
errors.Is percorre a cadeia de erros comparando com o alvo. Como retornamos o próprio ErrDivisaoPorZero, a comparação é direta. Isso é idiomático em Go: erros sentinela permitem que o chamador tome decisões sem depender de strings.
Erros comuns
- Criar um novo erro em vez de retornar o sentinela:
return 0, errors.New("divisão por zero")faz com queerrors.Isfalhe, pois são instâncias diferentes. - Comparar com
==:if err == ErrDivisaoPorZerofunciona apenas se o erro não for envolto; prefiraerrors.Is. - Esquecer de tratar o erro: ignorar o erro e usar o resultado pode causar divisão por zero silenciosa.
Outra forma de resolver
Se o erro não precisar ser um sentinela, pode-se usar fmt.Errorf sem %w e comparar a mensagem, mas isso é frágil. A forma com sentinela é preferível.
Saída esperada
Erro: divisão por zero