简体   繁体   English

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

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

Background 背景

In Smalltalk, if you don't excplicitly return anything then the message passing evaluates to the receiver (or "self" in the message context). 在Smalltalk中,如果您没有明确地返回任何内容,则传递的消息将评估为接收者(或消息上下文中的“self”)。

For example, given this method: 例如,给定此方法:

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

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

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

If <print-it> is done to the last invocation, then the result would be the instance itself. 如果对最后一次调用执行<print-it>,则结果将是实例本身。

Questions 问题

  • Why was this designed this way? 为什么这样设计?
  • What is the idea behind it? 它背后的想法是什么?
  • What was the philosophical background? 哲学背景是什么?
  • What are the practical benefits from it? 它有什么实际好处? Is it to facilitate method chaining? 方便链接是否方便?

One very simple reason has not been stated yet: In the Virtual Machine, returning self is simpler and more efficient than returning any other object. 尚未说明一个非常简单的原因:在虚拟机中,返回self比返回任何其他对象更简单,更有效。

Smalltalk byte codes implement a stack machine. Smalltalk字节代码实现堆栈机器。 That means arguments are passed by pushing them onto a stack, rather than putting them into registers. 这意味着通过将参数推送到堆栈来传递参数,而不是将它们放入寄存器中。 In addition to the arguments as listed in the method signature, a hidden argument is always passed, which is the receiver of the message. 除了方法签名中列出的参数之外,还始终传递隐藏参数,该参数是消息的接收者。 So even for unary methods (those without arguments) the receiver is pushed onto the stack, then the method is executed, and the receiver value on the stack is how the method knows "self". 因此,即使对于一元方法(没有参数的那些),接收器被推入堆栈,然后执行该方法,并且堆栈上的接收器值是该方法如何知道“自我”。 By returning "self" if no explicit return statement is given, the VM can just leave the "self" oop on the stack, which saves at least one memory store operation. 如果没有给出明确的return语句,则返回“self”,VM可以在堆栈上保留“self”oop,这样可以节省至少一个内存存储操作。 So from an efficiency and simplicity standpoint, returning "self" is the most elegant thing to do. 因此,从效率和简单的角度来看,返回“自我”是最优雅的事情。

Smalltalk-80's Blue Book ( The Language and its Implementation ) doesn't say anything regarding why it returns receiver by default. Smalltalk-80的蓝皮书( 语言及其实现 )没有说明为什么它默认返回接收器。

However, there is a quote in page 27 (Section "Returning values" ) that might help you: 但是,第27页( “返回值”部分 )中的引用可能对您有所帮助:

"Even if no information needs to be communicated back to the sender, a receiver always returns a value for the message expression. Returning value indicates the response to the message is complete. (...)" “即使没有信息需要传回给发送者,接收者也总是返回消息表达式的值。返回值表示对消息的响应已完成。(...)”

Keep in mind that in Smalltalk methods are activated by means of message sends, so there is a complete round-trip for a message (that might end in a MessageNotUnderstood exception). 请记住,Smalltalk方法是通过消息发送激活的,因此消息有一个完整的往返(可能以MessageNotUnderstood异常结束)。 The concept of message sending is paramount. 消息发送的概念至关重要。

There are some good practice patterns on what to return depending on the intention of the message, but that's subject of other story. 根据信息的意图,有什么好的实践模式可以归还,但这是其他故事的主题。

I'm not a creator of a smalltalk, but it seems to be the best thing to do. 我不是smalltalk的创造者,但它似乎是最好的事情。

For example if you'll execute: 例如,如果您将执行:

var := myInstance myMethod.

then the question is: what do you want var to become? 然后问题是:你想要var变成什么? One option will be nil . 一个选项是nil But it's a bit confusing, because you are working with defined objects and nil is actually an undefined one. 但它有点令人困惑,因为你正在使用已定义的对象,而nil实际上是一个未定义的对象。 So you can treat it as you are assigning myInstance to var and just calling myMethod along the way. 因此,当您将myInstance分配给var并且沿途调用myMethod时,您可以对其进行处理。 Also this can be probably treated as a shorthand for 这也可以作为速记来对待

 var := myInstance myMethod; yourself.

If you'll look from the inside, then from all data available to the object itself the most appropriate thing is probably also self . 如果你从内部看,那么从对象本身可用的所有数据中,最合适的东西可能也是self Once again, the nil can be returned, but I've told my opinion on it before. 再一次, nil可以返回,但我之前已经告诉过我了。

In Smalltalk there is no such thing as a void method that returns nothing, and there is no type checking. 在Smalltalk中,没有返回任何内容的void方法,并且没有类型检查。 So a method just has to return something. 所以方法只需返回一些东西。 It's like the Object says: 就像对象说:

I can return myself for any method call by default because I always know about myself, and you can redefine this behavior in case you want me to return something else. 默认情况下,我可以返回自己进行任何方法调用,因为我总是了解自己,如果您希望我返回其他内容,您可以重新定义此行为。

Personally I think that returning nil might be good too, and Objective-C applications use nil stuff very often, but Smalltalk is made this way and I think it's a quite good solution. 我个人认为返回nil也可能很好, Objective-C应用程序经常使用nil ,但是Smalltalk是这样做的,我认为这是一个非常好的解决方案。

Methods return self by default for several reasons. 默认情况下,方法返回self有几个原因。

  1. Smalltalk methods must return something Smalltalk方法必须返回一些东西
  2. self is the easiest object to return 自我是最简单的回归对象
  3. self is the fastest object to return 自我是最快的回归对象
  4. Returning self allows several design patterns to work naturally 返回自我允许几种设计模式自然地工作

Let me explain #4 a bit more. 让我再解释一下#4。 One common pattern for object initialization is to define a new method for the class which looks like this: 对象初始化的一种常见模式是为类定义一个方法,如下所示:

new
   ^super new initialize

This pattern depends on initialize returning self. 这种模式取决于初始化返回自我。 It's not normal, however, to add a ^self at the end of an initialize method. 但是,在初始化方法结束时添加^ self是不正常的。 It's unnecessary because the method will return self anyway. 这是不必要的,因为该方法无论如何都会返回自己。

In the end, returning self is just a natural choice by default given that you must return something. 最后,假设您必须返回一些东西,返回自我只是默认情况下的自然选择。

Coming from Java you know of NullPointExceptions when dealing with undefined return values. 来自Java,您在处理未定义的返回值时知道NullPointExceptions。 Furthermore your code has to do conditional checking for null here and there. 此外,您的代码必须在此处进行空值的条件检查。

Therefore I was happy to find a return value for every method invocation or message send in Smalltalk. 因此,我很高兴为Smalltalk中的每个方法调用或消息发送找到返回值。 If you decide to have every method return some value you are about to ask what your default value could be. 如果您决定让每个方法都返回一些值,那么您将要询问您的默认值是什么。 The object itself (self) is a very natural way to use as default value. 对象本身(self)是一种非常自然的默认值。 Or to ask the other way round: what could be a better return value? 或者反过来问:什么可以是更好的回报价值?

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

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