【发布时间】:2014-09-16 20:02:33
【问题描述】:
虽然 with goto's 很容易(如 f.ex. IL 所证明的那样),但我想知道是否也可以消除 all goto 语句更高级别表达式和语句 - 比如说 - 使用 Java 支持的所有内容。
或者,如果您喜欢:我正在寻找的是“重写规则”,无论 goto 的创建方式如何,它都将始终有效。
这主要是作为一个理论问题,纯粹是兴趣;不是好/坏的做法。
我想到的显而易见的解决方案是使用这样的东西:
while (true)
{
switch (state) {
case [label]: // here's where all your goto's will be
state = [label];
continue;
default:
// here's the rest of the program.
}
}
虽然这可能会起作用并且确实符合我的“正式”问题,但我一点也不喜欢我的解决方案。一方面,它非常丑陋,另一方面,它基本上将 goto 包装到一个开关中,该开关的作用与 goto 完全相同。
那么,有没有更好的解决方案?
更新 1
由于很多人似乎认为这个问题“过于宽泛”,所以我将详细说明...我提到 Java 的原因是因为 Java 没有“goto”语句。作为我的业余项目之一,我试图将 C# 代码转换为 Java,这被证明是非常具有挑战性的(部分原因是 Java 的这种限制)。
这让我开始思考。如果你有 f.ex.开放寻址中“删除”方法的实现(参见:http://en.wikipedia.org/wiki/Open_addressing - 注 1),在特殊情况下使用“goto”非常方便,尽管在这种特殊情况下您可以通过引入“状态”来重写它' 多变的。请注意,这只是一个示例,我已经为 continuation 实现了代码生成器,当您尝试反编译它们时会产生大量的 goto。
我也不确定在这件事上重写是否总是会消除“goto”语句,以及是否在每种情况下都允许。虽然我不是在寻找正式的“证据”,但在这件事上可以消除一些证据会很好。
所以关于“广泛性”,我挑战所有认为有“太多答案”或“重写 goto 的多种方法”的人,以提供一种算法或方法来重写一般情况,因为唯一的到目前为止我找到的答案是我发布的答案。
【问题讨论】:
-
goto是一种 hack,可以提高边缘情况下的性能(从实际的角度来看:标记器、IL 执行引擎和内核)。在任何情况下它都永远不可替代。 -
您知道
while、for和其他循环结构在内部使用goto 吗?所以你想避免使用循环?试图避免 switch 语句是没有意义的。好吧,您可以重构开关以使用多态性,但至少应该有一个。 -
@SriramSakthivel 许多语言确实碰巧通过使用跳转语句来实现这些结构,但这不是概念上的要求;还有其他实现这些结构的方法,只是它们在主流编程语言中并不常用。
-
@SriramSakthivel C# 只是代码规范,任何人都可以编写其实现。 C# 语言的 Microsoft 实现恰好具有特定实现细节这一事实并不能使该属性成为 C# 语言本身的事实。
-
@StefandeBruijn
goto本身并不邪恶。它的操作和控制流程缺乏透明度,被认为是“最好避免”。每个while也可以写成for,但是它们都没有生成真正意大利面条的内在能力,这就是为什么它们都存在方便。goto的灵活性也意味着形式化将非常困难,如果不是不可能的话,因为它本质上是对装配级构造的封装。我怀疑你会在那儿完全成功:)
标签: c# goto code-elimination