繁体   English   中英

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

[英]Why do methods return “self” by default in Smalltalk?

背景

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

例如,给定此方法:

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

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

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

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

问题

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

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

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

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

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

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

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

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

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

例如,如果您将执行:

var := myInstance myMethod.

然后问题是:你想要var变成什么? 一个选项是nil 但它有点令人困惑,因为你正在使用已定义的对象,而nil实际上是一个未定义的对象。 因此,当您将myInstance分配给var并且沿途调用myMethod时,您可以对其进行处理。 这也可以作为速记来对待

 var := myInstance myMethod; yourself.

如果你从内部看,那么从对象本身可用的所有数据中,最合适的东西可能也是self 再一次, nil可以返回,但我之前已经告诉过我了。

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

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

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

默认情况下,方法返回self有几个原因。

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

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

new
   ^super new initialize

这种模式取决于初始化返回自我。 但是,在初始化方法结束时添加^ self是不正常的。 这是不必要的,因为该方法无论如何都会返回自己。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM