了解带有多个冒号的 Smalltalk 方法调用

问题描述 投票:0回答:2

我目前正在学习 Smalltalk,在使用多个冒号的方法调用方面遇到了一种令人困惑的行为。我知道冒号在 Smalltalk 中指定方法名称及其参数方面起着至关重要的作用,但我很难理解为什么以下两种情况会导致不同的结果:

示例1:

100 max: 50 max: 102

示例2:

6 gcd: 3 factorial: 5

在示例 1 中,Smalltalk 尝试查找具有三个参数的名为 'max:max:' 的方法,而在示例 2 中,它正确地将冒号解释为单独的消息,导致 'gcd: 3''阶乘:5'

我希望能够澄清导致 Smalltalk 解释器产生这些不同解释的具体语法和结构方面。此外,任何有关 Smalltalk 如何在方法调用中处理冒号的见解都会有所帮助。

感谢您的协助!

syntax smalltalk method-invocation
2个回答
0
投票

除非您使用括号,否则关键字消息将发送查找具有所有关键字的方法。所以,是的,第一个示例查找名为 #'max:max:' 的单个方法,第二个示例查找名为 #'gcd:factorial:' 的单个方法。如果接收者的类中没有具有预期名称的方法,那么系统将报告错误。

因此,如果第二个表达式成功,那么您的图像中就有了 #'gcd:factorial' 的方法(这似乎有些令人惊讶)。您使用什么方言和版本的 Smalltalk?


0
投票

在 Smalltalk 中,消息选择器分为三种类型:一元选择器(例如,

2 negated
)、二元选择器(例如,
2 + 3
)和关键字选择器(例如,
2 max: 3
2 min: 20 max: 10
)。没有运算符优先级,但消息从左到右计算,您可以使用括号来控制计算顺序。

在示例 1 中,Smalltalk 尝试查找具有三个参数的名为“max:max:”的方法,而在示例 2 中,它正确地将冒号解释为单独的消息,结果是“gcd: 3”和“factorial: 5”。

对于我所知道的任何 Smalltalk 方言来说,这是错误的。不存在“选择器自动组合”这样的东西。如果您的

2
实现响应消息
max:max:
,即
SmallInteger
或其超类之一定义了此选择器的方法,则将执行此方法。否则,
doesNotUnderstand:
将被发送到通常会引发
MessageNotUnderstood
错误的对象。类似地,
6 gcd: 3 factorial: 5
将触发DNU,因为没有这样的方法。

顺便说一句,我不知道有任何带参数的阶乘方法(数学阶乘

n!
是一个一元函数,在 Smalltalk 中实现为
Number>>factorial
,例如
3 factorial
),所以为了论证我将使用
raisedTo:
来代替,它计算接收者对参数的幂。

如果您想明确表示要先发送

gcd:
,请使用括号:

(6 gcd: 3) raisedTo: 5

要先计算幂,请使用其他括号:

6 gcd: (3 raisedTo: 5)

HTH?

© www.soinside.com 2019 - 2024. All rights reserved.