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

时间:2012-12-27 00:15:24

标签: oop smalltalk pharo squeak visualworks

背景

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

例如,给定此方法:

MyClass >> myMethod
  Transcript show: 'hello'; cr.

评估(doint“print-it”)这个:

| myInstance |
myInstance := MyClass new.
myInstance myMethod.

如果< print-it>完成最后一次调用,结果就是实例本身。

问题

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

5 个答案:

答案 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有几个原因。

  1. Smalltalk方法必须返回
  2. self是最容易返回的对象
  3. self是最快回归的对象
  4. 返回自我允许多种设计模式自然地工作
  5. 让我再解释一下#4。对象初始化的一种常见模式是为类定义 new 方法,如下所示:

    new
       ^super new initialize
    

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

    最后,假设您必须返回某些东西,返回自我只是默认情况下的自然选择。

答案 4 :(得分:0)

来自Java,您在处理未定义的返回值时知道NullPointExceptions。此外,您的代码必须在此处进行空值的条件检查。

因此,我很高兴为Smalltalk中的每个方法调用或消息发送找到返回值。如果您决定让每个方法都返回一些值,那么您将要询问您的默认值是什么。对象本身(self)是一种非常自然的默认值。或者反过来问:什么可能是更好的回报值?