【问题标题】:Why do methods return "self" by default in Smalltalk?为什么方法在 Smalltalk 中默认返回“self”?
【发布时间】:2012-12-12 10:37:12
【问题描述】:

背景

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

例如,给定这个方法:

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

评估(点“打印”)这个:

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

如果 执行到最后一次调用,则结果将是实例本身。

问题

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

【问题讨论】:

  • 关于相关主题的有趣注释:块返回最后一个表达式的结果。

标签: oop smalltalk pharo squeak visualworks


【解决方案1】:

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

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

【讨论】:

  • 我的直觉是你成功了。这听起来与您在 Smalltalk-80 的原始实现中发现的那种优化完全一样。
【解决方案2】:

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

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

“即使不需要将任何信息回传给发送者,接收者也总是为消息表达式返回一个值。返回值表示对消息的响应已完成。(... )"

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

根据消息的意图,有一些关于返回什么的良好实践模式,但这是其他故事的主题。

【讨论】:

    【解决方案3】:

    我不是闲聊的创造者,但这似乎是最好的选择。

    例如,如果你将执行:

    var := myInstance myMethod.
    

    那么问题是:你希望var 变成什么?一种选择是nil。但这有点令人困惑,因为您正在使用已定义的对象,而 nil 实际上是未定义的对象。因此,您可以将其视为将 myInstance 分配给 var 并一路调用 myMethod 。这也可能被视为

    的简写
     var := myInstance myMethod; yourself.
    

    如果你从内部看,那么从对象本身可用的所有数据来看,最合适的可能也是self。再一次,nil 可以退回,但我之前已经说过我的意见了。

    在 Smalltalk 中,没有像 void 这样什么都不返回的方法,也没有类型检查。所以一个方法只需要返回一些东西。就像对象说的:

    默认情况下,我可以为任何方法调用返回自己,因为我总是 了解我自己,如果你愿意,你可以重新定义这种行为 我要还其他东西。

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

    【讨论】:

      【解决方案4】:

      方法默认返回 self 有几个原因。

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

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

      new
         ^super new initialize
      

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

      归根结底,返回 self 只是默认情况下的自然选择,因为您必须返回一些东西。

      【讨论】:

      • 是的,返回self 有助于“链接”消息。这个想法也可以在(一些)Java 方法中找到。
      【解决方案5】:

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

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

      【讨论】:

        猜你喜欢
        • 2013-04-18
        • 2016-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-01
        • 2012-03-17
        • 2018-09-03
        • 1970-01-01
        相关资源
        最近更新 更多