web-dev-qa-db-ja.com

Goに「goto」ステートメントがあるのはなぜですか

GoogleのGo言語は新しい言語です。そのため、 'goto' ステートメントがあることに驚いた。 「goto」ステートメントは過去のものであり、プログラムの実際の流れを妨げるために悪であるといつも教えられてきました。関数(または必要に応じてメソッド)は、常にフローを制御するためのより良い方法です。

私は何かが欠けているに違いない。なぜいつ「goto」を使用するのが良いでしょうか?または、なぜGoogleに含まれているのですか?

91
harm

実際にGosソースコード(標準ライブラリ)を確認すると、gotosが実際に適切に適用されていることがわかります。

たとえば、math/gamma.goファイル、 gotoステートメントが使用されます

  for x < 0 {
    if x > -1e-09 {
      goto small
    }
    z = z / x
    x = x + 1
  }
  for x < 2 {
    if x < 1e-09 {
      goto small
    }
    z = z / x
    x = x + 1
  }

  if x == 2 {
    return z
  }

  x = x - 2
  p = (((((x*_gamP[0]+_gamP[1])*x+_gamP[2])*x+_gamP[3])*x+_gamP[4])*x+_gamP[5])*x + _gamP[6]
  q = ((((((x*_gamQ[0]+_gamQ[1])*x+_gamQ[2])*x+_gamQ[3])*x+_gamQ[4])*x+_gamQ[5])*x+_gamQ[6])*x + _gamQ[7]
  return z * p / q

small:
  if x == 0 {
    return Inf(1)
  }
  return z / ((1 + Euler*x) * x)
}

この場合のgotoにより、制御フローのためだけに使用され、最後にチェックされる別の(ブール)変数を導入する必要がなくなります。 この場合gotoステートメントは実際にコードを読みやすくし、フォローしやすくします(言及したgotoに対する引数とは反対に)。

また、gotoステートメントには非常に具体的なユースケースがあることに注意してください。 gotoの言語仕様 は、スコープに入る変数(宣言されている)を飛び越えたり、他の(コード)ブロックに飛び移ったりしないことを示しています。

70
Kissaki

Gotoは、組み込みの制御機能のいずれも必要な機能をまったく実行できない場合や、gotoで必要な機能を表現できる場合に適しています。 (これらの場合、gotoを持たない一部の言語では残念です。ブールフラグを使用したり、gotoよりも悪い他のソリューションを使用したりして、何らかの制御機能を乱用することになります。)

他の制御機能(合理的に明白な方法で使用)が希望することを実行できる場合は、gotoよりも優先して使用する必要があります。そうでない場合は、太字にしてgotoを使用してください!

最後に、Goのgotoには、不明瞭なバグを回避するためのいくつかの制限があることに注意してください。 仕様 のこれらの制限を参照してください

24
Sonia

60年代と70年代の スパゲッティコード の時代以来、後藤の声明は多くの信用を失いました。当時、ソフトウェア開発方法論は非常に貧弱でした。ただし、Gotoは本来悪ではありませんが、怠laなプログラマや熟練していないプログラマによって悪用されたり、悪用されたりする可能性があります。乱用されたGotoの多くの問題は、チームコードレビューなどの開発プロセスで解決できます。

gotoは、continuebreak、およびreturnと同じ技術的な方法でのジャンプです。これらは声明は同じように悪であるが、そうではないと主張することができます。

GoチームにGotoが含まれているのは、おそらくGotoが一般的なフロー制御プリミティブであるためです。さらに、Goの範囲には、バカに安全な言語を悪用できないようにすることは含まれないと結論付けられました。

3
Gustav