为什么Smalltalk中的方法默认返回"self"?

Seb*_* N. 10 oop smalltalk visualworks squeak pharo

背景

在Smalltalk中,如果您没有明确地返回任何内容,则传递的消息将评估为接收者(或消息上下文中的"self").

例如,给定此方法:

MyClass >> myMethod
  Transcript show: 'hello'; cr.
Run Code Online (Sandbox Code Playgroud)

评估(doint"print-it")这个:

| myInstance |
myInstance := MyClass new.
myInstance myMethod.
Run Code Online (Sandbox Code Playgroud)

如果对最后一次调用执行<print-it>,则结果将是实例本身.

问题

  • 为什么这样设计?
  • 它背后的想法是什么?
  • 哲学背景是什么?
  • 它有什么实际好处?方便链接是否方便?

Ber*_*erg 12

尚未说明一个非常简单的原因:在虚拟机中,返回self比返回任何其他对象更简单,更有效.

Smalltalk字节代码实现堆栈机器.这意味着通过将参数推送到堆栈来传递参数,而不是将它们放入寄存器中.除了方法签名中列出的参数之外,还始终传递隐藏参数,该参数是消息的接收者.因此,即使对于一元方法(没有参数的方法),接收器被推入堆栈,然后执行该方法,并且堆栈上的接收器值是方法知道"自我"的方式.如果没有给出明确的return语句,则返回"self",VM可以将"self"oop留在堆栈上,这样可以节省至少一个内存存储操作.因此,从效率和简单的角度来看,返回"自我"是最优雅的事情.


ema*_*olo 6

Smalltalk-80的蓝皮书(语言及其实现)没有说明为什么它默认返回接收器.

但是,第27页("返回值"部分)中的引用可能对您有所帮助:

"即使没有信息需要传回给发送者,接收者也总是返回消息表达式的值.返回值表示对消息的响应已完成.(...)"

请记住,Smalltalk方法是通过消息发送激活的,因此消息有一个完整的往返(可能以MessageNotUnderstood异常结束).消息发送的概念至关重要.

根据信息的意图,有什么好的实践模式可以归还,但这是其他故事的主题.


Dav*_*uck 6

出于多种原因,方法默认返回 self 。

  1. Smalltalk 方法必须返回一些东西
  2. self 是最容易返回的对象
  3. self 是返回最快的对象
  4. Returning self 允许几种设计模式自然地工作

让我再解释一下#4。对象初始化的一种常见模式是为类定义一个方法,如下所示:

new
   ^super new initialize
Run Code Online (Sandbox Code Playgroud)

这种模式取决于初始化返回的自我。然而,在initialize方法的末尾添加^self是不正常的。这是不必要的,因为该方法无论如何都会返回 self 。

最后,默认情况下,返回 self 只是一个自然的选择,因为您必须返回一些东西。


Uko*_*Uko 5

我不是smalltalk的创造者,但它似乎是最好的事情.

例如,如果您将执行:

var := myInstance myMethod.
Run Code Online (Sandbox Code Playgroud)

然后问题是:你想var成为什么?一种选择是nil.但它有点令人困惑,因为您正在使用已定义的对象,nil实际上是一个未定义的对象.因此,您可以在分配时对待它myInstance,var并在此过程中调用myMethod.这也可以作为速记来对待

 var := myInstance myMethod; yourself.
Run Code Online (Sandbox Code Playgroud)

如果您从内部看,那么从对象本身可用的所有数据中,最合适的事情也可能是self.nil可以再次返回,但我之前已经告诉了我的意见.

在Smalltalk中,没有返回任何内容的void方法,并且没有类型检查.所以方法只需返回一些东西.就像对象说:

默认情况下,我可以返回任何方法调用,因为我总是了解自己,如果您希望我返回其他内容,您可以重新定义此行为.

我个人认为返回nil可能也很好,Objective-C应用程序nil经常使用东西,但Smalltalk是这样制作的,我认为这是一个非常好的解决方案.