Smalltalk 具有通过递归(在 VisualWorks 中)或通过编译器内联(在 Squeak/Pharo 中)实现的 whileTrue:-Message。有没有办法在不使用其中一个的情况下定义这样的方法?如果没有,是否有证据证明在某处可用?
最佳答案
我提出以下解决方案:
BlockContext>>myWhileTrue: aBlock
| start |
start := thisContext pc.
self value ifFalse: [ ^ self ].
aBlock value.
thisContext pc: start
上面的代码没有使用递归和编译器技巧,而是在执行堆栈上使用反射。在循环开始之前,该方法将当前程序计数器存储在一个临时变量中,并在结束时将其重置以跳回到方法的开头。在一些 Smalltalk 实现中,这种方法可能会很慢,因为一些 Smalltalk 方言仅按需具体化堆栈,但在 Pharo/Squeak 中,这个技巧非常可行。
注意,上面的代码没有像#whileTrue: 的原始实现那样回答最后一个块激活的结果。不过,解决这个问题应该很容易。
关于smalltalk - 有没有办法在仅消息语言中定义 whileTrue 消息而无需递归或编译器技巧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2500483/