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 ErrDivisaoPorZero com errors.New.
  • A função Dividir retorna (0, ErrDivisaoPorZero) quando b == 0.
  • No main, usar errors.Is para 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

  1. Declaramos ErrDivisaoPorZero como um erro sentinela usando errors.New. Isso cria um valor único que pode ser comparado depois.
  2. A função Dividir verifica se b == 0; se sim, retorna 0 e o erro sentinela.
  3. No main, chamamos Dividir(10, 0) e capturamos o erro.
  4. Usamos errors.Is(err, ErrDivisaoPorZero) para verificar se o erro é exatamente o sentinela (ou o envolve).
  5. 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 que errors.Is falhe, pois são instâncias diferentes.
  • Comparar com ==: if err == ErrDivisaoPorZero funciona apenas se o erro não for envolto; prefira errors.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