Après avoir été torturé pendant 13 ans, comment Go résout-il la fosse de réaffectation ?

Bonjour à tous, je suis poisson frit.

En examinant certaines propositions historiques de Go récemment, j'ai découvert qu'il existe des propositions très magiques, qui ont été proposées pendant de nombreuses années, mais elles ne sont toujours pas fermées aujourd'hui, et les gens en discutent constamment, mais elles ne peuvent pas être résolues.

Il y a une sorte de "très en colère et je ne peux pas me tuer", et aujourd'hui je vais emmener tout le monde voir ce que c'est.

Contexte

La proposition Go " proposition: spec: diverses modifications apportées à := " introduites dans cet article aujourd'hui est un classique parmi les classiques, et c'est un problème courant pour les débutants à apprendre.

La proposition existe depuis 2009 et a été discutée vigoureusement pour la dernière fois en 2021 :

Le prototype de code est le suivant :

func f() (err os.Error) {
	v, err := g()
	if err != nil {
		return
	}
	if v {
		v, err := h()
		if err != nil {
			return
		}
	}
}
复制代码

Le problème avec ce code est que le := dans l'instruction if entraîne une nouvelle variable err, ce qui entraîne l'écrasement du paramètre de retour.

C'est-à-dire que la logique de := réaffectation dans Go entraînera l'écrasement des paramètres, provoquant des problèmes cachés.

nouvelle proposition

Comme mentionné au début, il s'agit d'une proposition qui n'a pas pris fin en 2022 après 13 ans.

En résumant l'ensemble de la proposition et d'autres idées, nous avons proposé les solutions ou idées suivantes :

  • Ajouter du sucre syntaxique.
  • Débarrassez-vous de la grammaire.
  • fixer des spécifications.

ajouter du sucre syntaxique

L'idée supprime la redeclaration := syntaxe et ajoute une nouvelle syntaxe : et :: pour les nouvelles déclarations de variables.

Le code suivant :

package bar

func foo() {
   var x, err = f()
   ...
   // 这里 “:err” 表示上面声明的 err。 
   var y, z, :err = g()
   ...
   {
    // 实际上,:err 表示代码区块里的已经声明的 err。
   	var w, :err = h()
   	...
   	// ::err 表示包级别声明的 err。
   	var u, v, ::err = j()
   	...
   	// 这个“err”是一个新的声明。
   	var m, n, err = k()
   	...
   }
}
复制代码

Trois cas sont donnés dans le code ci-dessus, à savoir :

  • var :err = x : indique l'erreur déclarée dans la portée la plus récente, et la signification originale fait référence à l'erreur déclarée ci-dessus, vous trouverez donc des résultats différents dans le bloc de code et à l'extérieur.
  • var ::err = x : représente l'erreur déclarée au niveau du package.
  • var err = x : Indique une nouvelle déclaration.

tuer la grammaire

Dans une autre proposition " proposition: Go 2: let := support any l-value that = supports ", @Rob Pike, le père du langage Go, a directement déclaré qu'il voulait tuer := ce mode de réaffectation, au lieu de bricoler et ajouter un bouquet sera plus compliqué.

Comme indiqué ci-dessous:

Je pense que nous devrions viser à éliminer la redéclaration, si nous pouvons construire un modèle de gestion des erreurs plus fluide, la redéclaration devient moins perceptible. Mais cela n'arrivera pas de sitôt.

Supprimez des fonctionnalités au lieu de les ajouter.

(criant : moins c'est plus)

Plusieurs déclarations sur une seule ligne

Modifiez d'abord la sémantique de la réaffectation, tous les identifiants à gauche de := sont toujours déclarés comme de nouvelles variables, la redéclaration au sein d'un même bloc n'est pas autorisée.

Le code suivant :

a, err := foo()
b, err := foo() // 编译错误,因为 var err 已在此块中声明
复制代码

La déclaration de la première ligne est normale, la deuxième ligne est redéclarée dans le même bloc de code, il y aura donc une erreur de compilation car elle a déjà été déclarée.

Ajoutez ensuite des fonctionnalités syntaxiques qui permettent de mélanger = et := sur une seule ligne. Le code suivant :

// a 和 err 被声明和初始化(相当于:a, err := foo()
a:=, err:= foo()

// b 被声明和初始化,而 err 只被赋予了一个新值
b:=, err= foo()
if true {
    // c 在 if 块中声明并初始化,并为 err 分配一个新值
    c:=, err= foo()
}
if true {
    // d 和 err 在 if 块中声明,err 被隐藏
    d:=, err:= foo()
}
复制代码

Autoriser plusieurs déclarations sur une seule ligne clarifie essentiellement la portée de la déclaration et augmente la complexité de la lisibilité du code.

Résumer

L'article d'aujourd'hui vous présente une fosse découverte il y a 13 ans (2009). Lorsque j'ai appris Go pour la première fois, j'ai également rencontré de nombreux didacticiels et documents. Les étudiants rencontraient cette fosse de déclaration de réaffectation.

En fait, les trois schémas ci-dessus semblent compléter ce sucre syntaxique redéclaré sous différents angles, mais en augmentent également la complexité.

Peut-être juste le tuer, peut-être que c'est un bon choix ?

L'article est continuellement mis à jour, vous pouvez le lire sur WeChat en recherchant [Brain Fried Fish]. Cet article a été inclus sur GitHub github.com/eddycjy/blo… Si vous apprenez la langue Go, vous pouvez voir la carte d'apprentissage Go et route .Bienvenue sur Star pour vous inviter à mettre à jour.

Lecture recommandée

Je suppose que tu aimes

Origine juejin.im/post/7099302524607266829
conseillé
Classement