在Smalltalk中,如果您没有明确地返回任何内容,则传递的消息将评估为接收者(或消息上下文中的“self”)。
例如,给定此方法:
MyClass >> myMethod
Transcript show: 'hello'; cr.
评估(doint“print-it”)这个:
| myInstance |
myInstance := MyClass new.
myInstance myMethod.
如果< print-it>完成最后一次调用,结果就是实例本身。
答案 0 :(得分:11)
尚未说明一个非常简单的原因:在虚拟机中,返回self比返回任何其他对象更简单,更有效。
Smalltalk字节代码实现堆栈计算机。这意味着通过将参数推送到堆栈来传递参数,而不是将它们放入寄存器中。除了方法签名中列出的参数之外,还始终传递隐藏参数,该参数是消息的接收者。因此,即使对于一元方法(没有参数的那些),接收器被推入堆栈,然后执行该方法,并且堆栈上的接收器值是该方法如何知道“自我”。如果没有给出明确的return语句,则返回“self”,VM可以在堆栈上保留“self”oop,这样可以节省至少一个内存存储操作。因此,从效率和简单的角度来看,返回“自我”是最优雅的事情。
答案 1 :(得分:6)
Smalltalk-80的蓝皮书(语言及其实现)没有说明为什么它默认返回接收器。
但是,第27页(部分“返回值”)中的引用可能会对您有所帮助:
“即使没有信息需要传回发送方,接收方总是返回消息表达式的值。返回值表示对消息的响应已完成。(... )“
请记住,Smalltalk方法是通过消息发送激活的,因此消息有一个完整的往返(可能以MessageNotUnderstood异常结束)。消息发送的概念至关重要。
根据信息的意图,有哪些好的练习模式可以归还,但这是其他故事的主题。
答案 2 :(得分:5)
我不是小游戏的创造者,但它似乎是最好的事情。
例如,如果您执行:
var := myInstance myMethod.
然后问题是:你想要var
成为什么?一个选项是nil
。但它有点令人困惑,因为您正在使用已定义的对象,nil
实际上是一个未定义的对象。因此,您可以在将myInstance
分配给var
并在此过程中调用myMethod时对其进行处理。此外,这可能被视为
var := myInstance myMethod; yourself.
如果从内部看,那么从对象本身可用的所有数据中,最合适的事情可能也是self
。再次,nil
可以返回,但我之前已经告诉过我。
在Smalltalk中,没有返回任何内容的 void 方法,并且没有类型检查。所以方法只需返回一些东西。就像对象说的那样:
我可以默认返回任何方法调用,因为我总是这样 了解自己,你可以根据需要重新定义这种行为 我要归还别的东西。
就我个人而言,我认为返回nil
可能也很好, Objective-C 应用程序经常使用nil
这些东西,但是Smalltalk是这样制作的,我认为它是一个很好的解决方案。
答案 3 :(得分:3)
默认情况下,方法返回self有几个原因。
让我再解释一下#4。对象初始化的一种常见模式是为类定义 new 方法,如下所示:
new
^super new initialize
此模式取决于初始化返回self。但是,在初始化方法的末尾添加 ^ self 并不正常。这是不必要的,因为无论如何该方法都将返回自我。
最后,假设您必须返回某些东西,返回自我只是默认情况下的自然选择。
答案 4 :(得分:0)
来自Java,您在处理未定义的返回值时知道NullPointExceptions。此外,您的代码必须在此处进行空值的条件检查。
因此,我很高兴为Smalltalk中的每个方法调用或消息发送找到返回值。如果您决定让每个方法都返回一些值,那么您将要询问您的默认值是什么。对象本身(self)是一种非常自然的默认值。或者反过来问:什么可能是更好的回报值?