Erreurs
#
// En Go, il est idiomatique de communiquer les erreurs
// via une valeur de retour explicite et séparrée. Cela
// contraste avec les exceptions utilisées dans des
// languages comme Java ou Ruby, et ce qu'on retrouve
// en C, où l'on renvoit parfait une valeur, et parfois
// un code d'erreur. L'approche en Go fait qu'il est
// facile de voir quelles fonctions renvoient un code
// d'erreur et de les gérer en utilisant les mêmes
// constructions du langage utilisées pour n'importe
// quelle autre tâche sans erreur.
package main
import "errors"
import "fmt"
// Par convention, les erreurs sont la dernière valeur de
// retour et ont pour type `error`, une interface du
// langage.
func f1(arg int) (int, error) {
if arg == 42 {
// `errors.New` construit une valeur d'erreur
// basique avec le message d'erreur donné.
return -1, errors.New("can't work with 42")
}
// La valeur nil pour l'erreur indique qu'il n'y a
// pas eu d'erreurs.
return arg + 3, nil
}
// Il est possible d'utiliser des types d'erreurs sur
// mesure en implémentant la méthode `Error()` sur ces
// types. Voici une variante de l'exemple ci dessus qui
// utilise un type sur mesure pour représenter
// explicitement une erreur d'argument.
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 {
// Dans ce cas, nous utilisons la syntaxe
// `&argError` pour construire l'object et
// fournir les valeurs des deux champs `arg`
// et `prob`.
return -1, &argError{arg, "can't work with it"}
}
return arg + 3, nil
}
func main() {
// Les deux boucles ci-dessous testent chacunes de
// nos fonctions qui renvoient des erreurs. Notez que
// l'utilisation d'un test d'erreur inline dans le
// `if` est idiomatique en code 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)
}
}
// Si vous voulez utilisez les données d'une erreur
// custom, vous devrez récupérer l'erreur comme une
// instance du type d'erreur sur mesure en
// explicitant le type à utiliser.
_, e := f2(42)
if ae, ok := e.(*argError); ok {
fmt.Println(ae.arg)
fmt.Println(ae.prob)
}
}
$ go run errors.go
f1 worked: 10
f1 failed: can't work with 42
f2 worked: 10
f2 failed: 42 - can't work with it
42
can't work with it
# Regardez ce [bon article](http://blog.golang.org/2011/07/error-handling-and-go.html)
# sur le blog de Go pour plus d'informations
# sur la gestion d'erreurs.