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;
}