我正在努力教自己Smalltalk。 A tutorial有一个while循环的例子:
|i|
i:=5.
[i >0] whileTrue:[
Transcript show: ((i*2) asString) ; cr.
i:=i-1.
].
据我了解,whileTrue是发送给BlockClosure的消息,只要接收方为真,就告诉接收BlockClosure运行作为参数给出的BlockClosure。
如果没有Smalltalk中的while循环结构,BlockClosure响应的whileTrue消息是如何实现的?或者它是用运行时编写的任何语言实现的?
答案 0 :(得分:6)
在我的VisualWorks图像中,它是通过递归完成的:
whileTrue: aBlock ^self value ifTrue: [aBlock value. [self value] whileTrue: [aBlock value]]
但是,还有一个注释,如果接收器和参数都是文字块,编译器将内联一个#whileTrue:call。因此,在大多数情况下,您还可以考虑#whileTrue:看起来像语法上发送的消息的“神奇”消息之一,但实际上已经优化为不同的字节码。
答案 1 :(得分:0)
根据this forum whileTrue不是真实的消息。
答案 2 :(得分:0)
如前所述:编译器在我已知的所有实现中作弊和内联。因此,实际上不需要在正常情况下存在该方法,并且通常不会调用该方法。 但是,在不实际使用编译器的情况下执行或解释动态生成的代码结构时,该方法可能很有用。
顺便说一下,由于Smalltalk语言标准(实际上并不存在)并不强制实现消除尾部调用(例如,与Scheme相反),因此VW中的递归实现对于执行或解释(除非编译器作弊是标准化的)。
没有递归的替代方案可能是:
whileTrue:aBlock
self value ifFalse:[^ nil].
aBlock value.
thisContext restart