Pourquoi Go renvoie-t-il un pointeur vers un wrapper d'erreur mais le déclare-t-il avec « erreur » au lieu de « erreur » ? Il s’agit d’un problème courant rencontré par de nombreux développeurs du langage Go. En termes simples, la façon dont Go renvoie les erreurs est de faciliter son utilisation et sa gestion. Dans Go, une erreur est un type d'interface doté d'une méthode Error() qui renvoie un message d'erreur. Par conséquent, lorsqu’une fonction renvoie une erreur, elle renvoie en fait un pointeur vers une structure qui implémente la méthode Error(). Cette conception rend la gestion des erreurs plus concise et flexible, réduisant ainsi la redondance et la complexité du code. Ainsi, même si renvoyer un pointeur peut sembler étrange, il est en réalité destiné à fournir une meilleure gestion des erreurs.
J'apprends le langage Go à partir d'un arrière-plan Java.
type MyError struct { message string Offset int } func (Me *MyError) Error() string { return Me.message } func myFunction() (int, error) { <-- Why the return type is "error" rather than "*error" return 0, &MyError{"my error message", 0} <-- The error is returned as a pointer. } func main() { var _, err = myFunction() if e, ok := err.(*MyError); ok {. <-- Why I can assert err which is a type of "error" into a pointer fmt.Printf("Error is %s: %d\n", e.message, e.Offset) } }
Dans le code ci-dessus, je ne comprends pas pourquoi le type d'erreur de myFunction est « error » au lieu de « *error » ? Je renvoie clairement un pointeur vers la structure MyError dans la ligne ci-dessous.
Je comprends également pourquoi je peux affirmer l'erreur dans la fonction principale au pointeur.
Pour comprendre la gestion traditionnelle des erreurs dans Go, vous devez d'abord comprendre comment fonctionnent les interfaces du langage. Il y a deux choses à retenir lorsqu'on parle des interfaces Go :
Une interface dans Go définit un ensemble de méthodes (commencer par Go1.18 est aussi un ensemble de types). En coulisses, les interfaces Go contiennent deux éléments, des types T
和值 V
。 V
始终是具体类型,例如 int
、struct
ou des pointeurs, plutôt que l'interface elle-même.
Il n'y a pas de mot-clé implements
dans Go. Les types Go satisfont cette interface en implémentant ses méthodes. C’est ce qu’on appelle la mise en œuvre implicite.
Go définit un type error
intégré, qui n'est qu'une interface :
type error interface { Error() string }
En fait, cela n’a rien de spécial, sauf que c’est un type prédéfini global. Ce type est généralement utilisé pour la gestion des erreurs.
Prenez votre exemple :
func myFunction() (int, error) { return 0, &MyError{"my error message", 0} } func main() { var _, err = myFunction() if e, ok := err.(*MyError); ok { fmt.Printf("Error is %s: %d\n", e.message, e.Offset) } }
La relation entre le pointeur vers MyError
et l'interface MyError
的指针和 error
接口之间的关系发生在幕后,您不需要显式返回 *error
即可从 MyError
值引用 error
se produit en coulisses, vous n'avez pas besoin de renvoyer explicitement *error
pour obtenir la valeur de MyError
Référence (En fait, vous presque jamais besoin d'un pointeur vers une interface
myFunction
后,error
值将保存以下元组 (V=&MyError{message: "my error message", Offset: 0}, T=*MyError)
,其中 V
是它的值保持,T
是值 V
Après avoir renvoyé myFunction
, la valeur
(V=&MyError{message : "mon message d'erreur", Offset : 0}, T=*MyError)
, Où V
est sa valeur conservée et T
est le type de valeur V
.
e, ok := err.(*MyError)
是: err
值(哪种类型是 error
接口)是否将类型 *MyError
作为其底层 T
?如果是这样,则 ok
将是 true
,并且 e
将接收其底层 V
值 &MyError{message: "我的错误消息", Offset: 0}
Parce que Go vous permet de taper des assertions sur les valeurs de l'interface. Fondamentalement, ce que vous demandez à propos de l'opération Go e, ok := err.(*MyError)
est : si la valeur err
(quel type est l'interface
*MyError
comme son T
sous-jacent ? Si tel est le cas, alors ok
sera true
et e
recevra sa valeur V
sous-jacente &MyError {message : "Mon message d'erreur", Décalage : 0}
.
Remarquenil
: Veuillez traiter les valeurs d'erreur avec prudence, car elles peuvent ne pas toujours se comporter comme prévu
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!