有些(罕见的)情况下,goto实际上可以提高可读性。事实上,您链接到的文档列出了两个示例:
Goto的常见用途是将控制转移到switch语句中的特定case标签或默认标签。
Goto语句也可用于退出深度嵌套的循环。
以下是后者的示例:
for (...) {
for (...) {
...
if (something)
goto end_of_loop;
}
}
end_of_loop:
当然,还有其他解决这个问题的方法,比如将代码重构为一个函数,使用一些虚假的块包围它等(详见这个问题)。另外值得一提的是,Java语言设计者决定完全禁止goto语句,并引入了一个带标签的break语句。
break <label>
,这可以确保可靠性和安全性。 - mihsatheswitch (a)
{
case 3:
b = 7;
// We want to drop through into case 4, but C# doesn't let us
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
翻译成类似这样的内容
switch (a)
{
case 3:
b = 7;
goto case 4;
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
参考 这篇文章
我在Eduasync中广泛使用它,以展示在C# 5中使用异步方法时编译器为您生成的代码类型。您在迭代块中将看到相同的内容。
然而,在“普通”的代码中,我记不起上一次使用它是什么时候了...
goto
语句,例如在生成的迭代器块类型中(在使用yield return
关键字时生成 - 我很确定生成的XML序列化类型也有一些goto
语句)。有关C#编译器处理此问题的更多详细信息,请参见迭代器块实现详细信息:自动生成状态机。goto
语句的好理由 - 它使代码难以理解,因此更容易出错。另一方面,在像这样的生成代码中使用goto
语句可以简化生成过程,并且通常是可以接受的,因为没有人会阅读(或修改)生成的代码,并且没有机会发生错误,因为是机器进行编写。goto
则没有。这是需要考虑的事情。 - Dan Bechard我不记得曾经使用过goto
。但是可能它可以提高永远不想退出的循环的意图(没有break
,但是你仍然可以return
或throw
):
forever: {
// ...
goto forever;
}
再说了,一个简单的 while (true)
就足够了...
此外,在你想让循环的第一次迭代从循环中间开始的情况下,可能可以使用它:请看这里有一个例子。
goto
用法,而while(true) {..}
并不是一个有趣的用法。 - user2864740goto语句非常适用于跳出很多循环,如果使用break会不太合适(例如在错误条件下),正如Kragen所说,编译器也使用goto来生成switch语句和其他一些东西。
goto
似乎是个好主意,那么就是重构的时候了。结构化语言的目的是避免这些“跳转”,并在我们的工程中创建逻辑流程。break
,但我不能忽略它带来的性能好处。然而,如果我有相互需要break
的嵌套循环,那么就是重构的时候了。goto
用法,我会很高兴撤回我的答案。dynamic
对象并遍历其包含多个字典的对象图,以获取所需的值。使用具有 dynamic
参数但期望精确对象形状的方法没有意义。使用 goto 跳出多个层并继续遍历这些对象集合。[我不拥有类型,因此无法提供更好的访问方式,因此只能使用反射或动态方式] - Chris Marisic使用goto语句并不是最好的选择。而且continue、break(除了在switch/case中)、(多个)return和throw也应该尽可能地减少使用。你永远不想从嵌套循环的中间跳出。你总是希望循环控制语句具有所有的循环控制权。缩进包含了信息,而所有这些语句都会抛弃这些信息。你最好将所有缩进都去掉。
goto
根据特定条件打破循环并返回到起始语句。 - Nitin Sawant