虽然使用goto语句制作所有内容很容易(例如IL),但我想知道是否也可以使用高级表达式和语句-比如Java中支持的一切-消除所有goto语句。
或者说,我正在寻找“重写规则”,它们始终有效,而不管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的这种限制)。
这让我想起了一些事情。如果你有Open addressing中“remove”方法的实现(参见:http://en.wikipedia.org/wiki/Open_addressing - 注意1),在异常情况下使用“goto”是非常方便的,尽管在这种特殊情况下,你可以通过引入“状态”变量来重写它。请注意,这只是一个例子,当你试图反编译它们时,我已经为continuations实现了代码生成器,这会产生大量的goto。
我也不确定以这种方式进行重写是否总是会消除“goto”语句,以及在每种情况下是否允许。虽然我不寻求正式的“证明”,但一些证据表明,在这种情况下消除是可能的,这将是非常好的。
关于“广泛性”,我向所有认为有“太多答案”或“重写goto的方式很多”的人发起挑战,请提供一种算法或方法来重写一般情况,因为迄今为止我找到的唯一答案就是我发布的那个。
goto
是一个可以在特定情况下提高性能的技巧(从实用角度来看:标记器、IL执行引擎和内核)。但它在任何情况下都不是不可替代的。 - Niels Keurentjesgoto
本身并不是邪恶的。它被认为是“最好避免”的,是因为它的操作缺乏透明度和控制流。每个while
循环也可以用for
循环来编写,但它们都没有生成真正意义上的代码混乱的内在能力,这就是它们作为方便存在的原因。goto
的灵活性也意味着形式化将非常困难,如果不是不可能的话,因为它本质上是汇编级别结构的封装。我怀疑你在那方面会完全成功 :) - Niels Keurentjes