Je ne fais que commencer avec Go. Mon code commence à en avoir beaucoup:
if err != nil {
//handle err
}
ou ca
if err := rows.Scan(&some_column); err != nil {
//handle err
}
Existe-t-il de bonnes idiomes / stratégies / bonnes pratiques pour vérifier et gérer les erreurs dans Go?
EDIT pour clarifier: je ne suis pas en train de faire du mal ou de suggérer que l'équipe Go propose quelque chose de mieux. Je demande si je fais les choses correctement ou si j'ai raté une technique que la communauté a inventée. Merci a tous.
Réponses:
Votre code est idiomatique et à mon avis, c'est la meilleure pratique disponible. Certains seraient en désaccord avec certitude, mais je dirais que c'est le style que l'on retrouve dans toutes les bibliothèques standard de Golang . En d'autres termes, les auteurs de Go écrivent la gestion des erreurs de cette manière.
la source
Six mois après cette question, Rob Pike a écrit un article de blog intitulé Les erreurs sont des valeurs .
Là-dedans, il fait valoir que vous n'avez pas besoin de programmer de la manière présentée par l'OP, et mentionne plusieurs endroits dans la bibliothèque standard où ils utilisent un modèle différent.
C'est une bonne lecture.
la source
Je serais d'accord avec la réponse de jnml selon laquelle ils sont tous deux du code idiomatique, et j'ajouterais ce qui suit:
Votre premier exemple:
est plus idiomatique lorsqu'il s'agit de plusieurs valeurs de retour. par exemple:
Votre deuxième exemple est un bon raccourci lorsqu'il ne traite que de la
err
valeur. Cela s'applique si la fonction renvoie uniquement unerror
, ou si vous ignorez délibérément les valeurs renvoyées autres que leerror
. À titre d'exemple, ceci est parfois utilisé avec les fonctionsReader
etWriter
qui renvoient unint
du nombre d'octets écrits (informations parfois inutiles) et unerror
:Le deuxième formulaire est appelé à utiliser une instruction d'initialisation if .
Donc en ce qui concerne les meilleures pratiques, pour autant que je sache (sauf pour l'utilisation du package "errors" pour créer de nouvelles erreurs lorsque vous en avez besoin), vous avez couvert à peu près tout ce dont vous avez besoin pour savoir sur les erreurs dans Go!
EDIT: Si vous trouvez que vous ne pouvez vraiment pas vivre sans exceptions, vous pouvez les imiter avec
defer
,panic
&recover
.la source
J'ai créé une bibliothèque pour une gestion simplifiée des erreurs et un acheminement via une file d'attente de fonctions Go.
Vous pouvez le trouver ici: https://github.com/go-on/queue
Il a une variante syntaxique compacte et verbeuse. Voici un exemple de syntaxe courte:
Sachez qu'il y a une légère surcharge de performance, car elle utilise la réflexion.
Ce n'est pas non plus du code go idiomatique, vous voudrez donc l'utiliser dans vos propres projets ou si votre équipe accepte de l'utiliser.
la source
Une «stratégie» pour gérer les erreurs en golang et dans d'autres langages est de propager continuellement les erreurs dans la pile d'appels jusqu'à ce que vous soyez suffisamment haut dans la pile d'appels pour gérer cette erreur. Si vous avez essayé de gérer cette erreur trop tôt, vous finirez probablement par répéter le code. Si vous le gérez trop tard, vous casserez quelque chose dans votre code. Golang rend ce processus très facile car il indique très clairement si vous gérez une erreur à un emplacement donné ou si vous la propagez.
Si vous allez ignorer l'erreur, un simple _ révélera ce fait très clairement. Si vous le gérez, le cas exact de l'erreur que vous gérez est clair car vous le vérifierez dans l'instruction if.
Comme les gens l'ont dit ci-dessus, une erreur n'est en fait qu'une valeur normale. Cela le traite comme tel.
la source
Les dieux de Go ont publié un "projet de conception" pour la gestion des erreurs dans Go 2. Il vise à changer l'idiome des erreurs:
Vue d'ensemble et conception
Ils veulent des commentaires des utilisateurs!
Wiki de commentaires
En bref, cela ressemble à:
MISE À JOUR: Le projet de conception a reçu beaucoup de critiques, j'ai donc rédigé les exigences à prendre en compte pour la gestion des erreurs Go 2 avec un menu de possibilités pour une solution éventuelle.
la source
La plupart dans l'industrie, suivent les règles standard mentionnées dans la documentation golang Gestion des erreurs et Go . Et cela facilite également la génération de documents pour le projet.
la source
Voici mon point de vue sur la réduction de la gestion des erreurs sur Go, un exemple est pour obtenir des paramètres d'URL HTTP:
(Modèle de conception dérivé de https://blog.golang.org/errors-are-values )
l'appeler pour plusieurs paramètres possibles serait comme ci-dessous:
Ce n'est pas une solution miracle, l'inconvénient est que si vous avez eu plusieurs erreurs, vous ne pouvez obtenir que la dernière erreur.
Mais dans ce cas, il est relativement répétitif et à faible risque, je peux donc simplement obtenir la dernière erreur possible.
la source
Vous pouvez nettoyer votre code de gestion des erreurs pour des erreurs similaires (puisque les erreurs sont des valeurs auxquelles vous devez faire attention ici) et écrire une fonction que vous appelez avec l'erreur transmise pour gérer l'erreur. Vous n'aurez pas à écrire "if err! = Nil {}" à chaque fois. Encore une fois, cela ne fera que nettoyer le code, mais je ne pense pas que ce soit la manière idiomatique de faire les choses.
Encore une fois, ce n'est pas parce que vous pouvez le faire .
la source
goerr permet de gérer les erreurs avec les fonctions
la source
Si vous voulez un contrôle précis des erreurs, ce n'est peut-être pas la solution, mais pour moi, la plupart du temps, toute erreur est un frein.
Donc, j'utilise des fonctions à la place.
la source
stderr
plutôt questdout
, alors utilisez simplementlog.Fatal(err)
oulog.Fatalln("some message:", err)
. Puisque presque rien d'autre quemain
ne devrait prendre une telle décision pour mettre fin à tout le programme (c'est-à-dire renvoyer des erreurs de fonctions / méthodes, ne pas abandonner) dans de rares cas, c'est ce que vous voulez faire, c'est plus propre et mieux vaut le faire explicitement (c'est-à-direif err := someFunc(); err != nil { log.Fatal(err) }
) plutôt que via une fonction "helper" qui n'est pas claire sur ce qu'elle fait (le nom "Err" n'est pas bon, il ne donne aucune indication qu'il peut terminer le programme).