Introdução
O objetivo deste laboratório é entender como lidar com erros em Golang.
Erros
O laboratório fornece duas funções que retornam um erro se o argumento de entrada for 42. A primeira função retorna um valor de erro básico, enquanto a segunda função usa um tipo personalizado para representar o erro.
- O pacote
errorsdeve ser importado. - A função
f1deve retornar um erro se o argumento de entrada for 42. - A função
f2deve retornar um erro do tipoargErrorse o argumento de entrada for 42. - O tipo
argErrordeve ter dois campos:argeprob. - O tipo
argErrordeve implementar o métodoError(). - A função
maindeve chamarf1ef2com argumentos de entrada 7 e 42. - A função
maindeve imprimir o resultado de cada chamada de função, juntamente com qualquer erro que foi retornado. - A função
maindeve demonstrar como usar programaticamente os dados em um erro personalizado.
## Veja esta [ótima publicação](https://go.dev/blog/error-handling-and-go)
## no blog do Go para mais informações sobre tratamento de erros.
Abaixo está o código completo:
// Em Go, é idiomático comunicar erros por meio de um
// valor de retorno explícito e separado. Isso contrasta com
// as exceções usadas em linguagens como Java e Ruby e
// o único resultado sobrecarregado / valor de erro às vezes
// usado em C. A abordagem do Go facilita a visualização de quais
// funções retornam erros e tratá-los usando o
// mesmas construções de linguagem empregadas para qualquer outra,
// tarefas não relacionadas a erros.
package main
import (
"errors"
"fmt"
)
// Por convenção, os erros são o último valor de retorno e
// têm o tipo `error`, uma interface embutida.
func f1(arg int) (int, error) {
if arg == 42 {
// `errors.New` constrói um valor `error` básico
// com a mensagem de erro fornecida.
return -1, errors.New("can't work with 42")
}
// Um valor `nil` na posição de erro indica que
// não houve erro.
return arg + 3, nil
}
// É possível usar tipos personalizados como `error`s por
// implementar o método `Error()` neles. Aqui está uma
// variante do exemplo acima que usa um tipo personalizado
// para representar explicitamente um erro de argumento.
type argError struct {
arg int
prob string
}
func (e *argError) Error() string {
return fmt.Sprintf("%d - %s", e.arg, e.prob)
}
func f2(arg int) (int, error) {
if arg == 42 {
// Neste caso, usamos a sintaxe `&argError` para construir
// uma nova struct, fornecendo valores para os dois
// campos `arg` e `prob`.
return -1, &argError{arg, "can't work with it"}
}
return arg + 3, nil
}
func main() {
// Os dois loops abaixo testam cada uma de nossas
// funções que retornam erros. Observe que o uso de um
// verificação de erro embutida na linha `if` é um comum
// idioma no código Go.
for _, i := range []int{7, 42} {
if r, e := f1(i); e != nil {
fmt.Println("f1 failed:", e)
} else {
fmt.Println("f1 worked:", r)
}
}
for _, i := range []int{7, 42} {
if r, e := f2(i); e != nil {
fmt.Println("f2 failed:", e)
} else {
fmt.Println("f2 worked:", r)
}
}
// Se você deseja usar programaticamente os dados em
// um erro personalizado, você precisará obter o erro como um
// instância do tipo de erro personalizado via tipo
// asserção.
_, e := f2(42)
if ae, ok := e.(*argError); ok {
fmt.Println(ae.arg)
fmt.Println(ae.prob)
}
}
Resumo
Este laboratório demonstra como lidar com erros em Golang usando a interface error e tipos de erro personalizados. Ele também mostra como usar programaticamente os dados em um erro personalizado.