13年間苦しめられた後、Goはどのように再割り当ての落とし穴を解決しますか?

みなさん、こんにちは。魚のフライです。

最近の囲碁の歴史的な提案を見てみると、何年にもわたって提案されてきた非常に不思議な提案がいくつかあることがわかりました。

ある種の「とても怒って私を殺せない」というものがありますが、今日はそれが何であるかをみんなに見てもらいます。

バックグラウンド

本日この記事で紹介した囲碁の提案「提案:仕様::=へのさまざまな変更」は古典の中でも古典であり、初心者が学ぶのは一般的な問題です。

この提案は2009年から出回っており、最近では2021年に活発に議論されました。

コードのプロトタイプは次のとおりです。

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

このコードの問題は、ifステートメントの:=が新しいerr変数になり、returnパラメーターが上書きされることです。

つまり、Goでの:= reassignmentのロジックにより、パラメーターが上書きされ、隠れた問題が発生します。

新しい提案

冒頭で述べたように、これは13年経っても2022年に終わらない提案です。

提案全体とその他のアイデアを要約して、次の解決策またはアイデアを提案しました。

  • シンタックスシュガーを追加します。
  • 文法を取り除く。
  • 仕様を設定します。

シンタックスシュガーを追加する

このアイデアは、再宣言:=構文を削除し、新しい変数宣言用に新しい:および::構文を追加します。

次のコード:

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()
   	...
   }
}
复制代码

上記のコードでは、次の3つのケースが示されています。

  • var:err = x:は、最新のスコープで宣言されたerrを示し、元の意味は上記で宣言されたerrを参照しているため、コードブロックと外部で異なる結果が見つかります。
  • var :: err = x:パッケージレベルで宣言されたエラーを表します。
  • var err = x:新しい宣言を示します。

文法を殺す

別の提案「提案:Go 2:let:=サポートするl値をサポートする」で、Go言語の父である@Rob Pikeは、いじくり回すのではなく、この方法で再割り当てを殺したいと直接述べました。束を追加すると、より複雑になります。

以下に示すように:

再宣言を排除することを目指すべきだと思います。よりスムーズなエラー処理モデルを構築できれば、再宣言は目立たなくなります。しかし、それはすぐには起こりません。

機能を追加する代わりに削除します。

(叫び:少ないほど多い)

1行に複数の宣言

最初に再割り当てのセマンティクスを変更します。:=の左側にあるすべての識別子は常に新しい変数として宣言され、同じブロック内での再宣言は許可されません。

次のコード:

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

最初の行の宣言は正常であり、2番目の行は同じコードブロックで再宣言されているため、すでに宣言されているため、コンパイルエラーが発生します。

次に、1行で=と:=を混合できる構文機能を追加します。次のコード:

// 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()
}
复制代码

1行で複数の宣言を許可すると、基本的に宣言の範囲が明確になり、コードの可読性が複雑になります。

要約する

今日の記事では、13年前(2009年)に発見されたピットを紹介します。Goを最初に学んだとき、私は多くのチュートリアルやドキュメントにも遭遇しました。学生はこの再割り当てステートメントの落とし穴に遭遇しました。

実際、上記の3つのスキームは、この再宣言された構文糖衣をさまざまな角度から補完しているように見えますが、複雑さも増しています。

多分それを殺すだけかもしれません、多分それは良い選択ですか?

記事は継続的に更新されており、WeChatで[Brain Fried Fish]を検索して読むことができます。この記事は、 GitHub github.com/eddycjy/bloに含まれています…Go言語を学習している場合は、 Go学習マップをご覧ください。とルート。スターへようこそ。更新を促します。

おすすめの読み物

おすすめ

転載: juejin.im/post/7099302524607266829