为什么这段代码不会导致无限循环?
Why doesn't this code cause an infinite loop?
假设我定义了一个新的 class,并且我覆盖了 class:
class
^self class.
然后我运行:
var:=NewClass new.
Transcript show:(var class);cr.
为什么这段代码不会导致无限循环?
运行时间class是NewClass
,那么代码怎么会调用Object
中定义的class,而不是[=23] =] 在 NewClass
?
中定义
Smalltalk 实现可能会为特殊消息实现某些快捷方式。您没有指定您的 Smalltalk 实现,但很可能它有一个特殊的字节码来检索对象的 class。当 Smalltalk VM 遇到该字节码时,它并没有真正将消息 class
发送给接收者,因此您的方法永远不会被调用,无限递归也不会发生。如果 Smalltalk 编译器发现您使用 class
.
,它将发出该特殊字节码而不是消息发送的字节码
ifTrue: ifFalse:
通常会发生同样的情况,Smalltalk 编译器将在“调用”方法的字节码中发出条件跳转,而不是将消息发送到接收者(布尔)对象。
要获得这样的无限循环,您可以在脚本和 NewClass>>class
的实现中尝试使用 perform: #class
。
class
^ self perform: #class
假设我定义了一个新的 class,并且我覆盖了 class:
class
^self class.
然后我运行:
var:=NewClass new.
Transcript show:(var class);cr.
为什么这段代码不会导致无限循环?
运行时间class是NewClass
,那么代码怎么会调用Object
中定义的class,而不是[=23] =] 在 NewClass
?
Smalltalk 实现可能会为特殊消息实现某些快捷方式。您没有指定您的 Smalltalk 实现,但很可能它有一个特殊的字节码来检索对象的 class。当 Smalltalk VM 遇到该字节码时,它并没有真正将消息 class
发送给接收者,因此您的方法永远不会被调用,无限递归也不会发生。如果 Smalltalk 编译器发现您使用 class
.
ifTrue: ifFalse:
通常会发生同样的情况,Smalltalk 编译器将在“调用”方法的字节码中发出条件跳转,而不是将消息发送到接收者(布尔)对象。
要获得这样的无限循环,您可以在脚本和 NewClass>>class
的实现中尝试使用 perform: #class
。
class
^ self perform: #class