goto ステートメントは実際にはどれほど悪いのでしょうか? またその理由は?
与えられたすべての通常の理由から、それは本当に悪いです。サポートされていない言語でラベル付きループをエミュレートする場合は、まったく問題ありません。
これを関数に置き換えると、多くの場合、実際には同じ単位として読み取られるべきロジックが散らばってしまいます。これにより、読みにくくなります。どこから出発したかをいくらか忘れてしまう旅の終わりまで、実際には何もしない機能の跡をたどりたいと思う人はいません。
それをブール値と追加の if と break で置き換えるのは本当に扱いにくく、ノイズのように本当の意図に従うのが難しくなります。
Java (およびJavaScript)では、これは完全に受け入れられます(ラベル付きのループ):
outer: while( true ) {
for( int i = 0; i < 15; ++i ) {
break outer;
}
}
C# では、非常に近いものはそうではないようです。
while( true ) {
for (int I = 0; I < 15; I++) {
goto outer;
}
}
outer:;
という言葉のせいで、goto
人々は常識をすべて捨て去り、文脈に関係なくxkcdをリンクさせるという心理的効果があります。
「goto」ステートメントを使用するよりもメインループを中断する効果的な方法はありますか?
ない場合もあります。そのため、他の言語ではラベル付きループが提供され、C# では が提供されますgoto
。あなたの例は単純すぎることに注意してください。回避策は例に合わせて調整されているため、それほど悪くはありません。実際、私はこれを提案することもできます:
for (int I = 0; I < 15; I++) {
break;
}
これはどう:
int len = 256;
int val = 65536;
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len; j++)
{
if (i + j >= 2 * val)
{
goto outer;
}
val = val / 2;
}
}
outer:;
これはまだあなたに似合いますか:
int len = 256;
int val = 65536;
for (int i = 0; i < len; i++)
{
if (!Inner(i, ref val, len))
{
break;
}
}
private bool Inner(int i, ref int val, int len)
{
for (int j = 0; j < len; j++)
{
if (i + j >= 2 * val)
{
return false;
}
val = val / 2;
}
return true;
}