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 error s 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)
}
}
|