|
No Go é idiomático comunicar erros através de um
explícito, valor de retorno separado. Isso contrasta com
as excessões usadas em linguagens como Java e Ruby e
resultados únicos sobrecarregados / valores de erros algumas vezes
usados em C. Go torna fácil ver quais funções
retornam erros e o tratamento deles usando construções da
mesma linguagem empregada para qualquer outra tarefa não-erro.
|
|
|
|
|
|
|
import "errors"
import "fmt"
|
|
Por convenção, erros são o último valor de retorno e
possuem o tipo error, uma interface integrada.
|
func f1(arg int) (int, error) {
if arg == 42 {
|
|
errors.New constrói um valor de error básico
com a mensagem de erro dada.
|
return -1, errors.New(não pode trabalhar com 42")
|
|
|
|
|
Um valor zero na posilção do erro indica que
não houve erro.
|
|
|
É possível usar tipos personalizados como errors através
da implementação do método Error() neles. Aqui temos uma
variante do exemplo acima que usa um tipo personalizado
para representar explicitamente um argumento de erro.
|
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 estrutura, fornecendo valores para os dois campos
arg e prob.
|
return -1, &argError{arg, não pode trabalhar com ele.}
}
return arg + 3, nil
}
|
|
|
|
|
Os dois loops do teste abaixo mostram cada uma das
funções retorno-erro. Note que o uso de um erro
inline verificada na linha if é um
idioma comum no código Go.
|
for _, i := range []int{7, 42} {
if r, e := f1(i); e != nil {
fmt.Println("f1 falhou:", e)
} else {
fmt.Println("f1 funcionou:", r)
}
}
for _, i := range []int{7, 42} {
if r, e := f2(i); e != nil {
fmt.Println("f2 falhou:", e)
} else {
fmt.Println("f2 funcionou:", r)
}
}
|
|
Se você quiser usar programaticamente dados em um
erro personalizado, você precisará pegar o erro como uma
instância do erro personalizado através do tipo afirmação.
|
_, e := f2(42)
if ae, ok := e.(*argError); ok {
fmt.Println(ae.arg)
fmt.Println(ae.prob)
}
}
|