5

Smalltalk(尤其是 Squeak/Pharo)是否具有某种形式的可变参数函数?

我只是在阅读有关在 smalltalk 中设计自己的控制语句的强大功能,而我是 ifTrue 的忠实粉丝: ifFalse:我很难想出一个好方法来实现任意 if、if else、if else ,...,else 语句认为可变参数函数对于实现 case 语句有多大用处。就像是

假类

ifTrue: aBlock (... elseIf: aBoolean then: aSecondBlock ...) else: aLastBlock

vArgList pairsDo: [:x :y| x ifTrue:[^ (y value)] ].
^ aLastBlock
4

3 回答 3

3

Smalltalk 用于方法调用的类似关键字的语法本质上定义了方法的数量。没有&rest像 Common Lisp 那样的模式。

你当然可以有一个方法来列出一个列表,BlockClosure>>valueWithArguments:但这几乎不是一回事。

您可以修改Compiler以支持可变方法调用。也许调用只是with:在每个变量之间进行:

(条件) ifTrue: aBlock elseIf: aBoolean with: aSecondBlock with: anotherBoolean with: aThirdBlock

于 2010-10-06T19:02:35.870 回答
1

您可以使用该#caseOf:otherwise:消息。例如,查找此消息的某些发件人。

但无论如何,如果你想使用 case 语句,你就没有遵循 smalltalk-of-doing-things。告诉我们您希望通过案例陈述实现的目标,以便我们向您展示一些更简洁的方法。

于 2010-10-11T21:26:39.300 回答
1

我在编程中学到的一件事不是你不需要 case 语句,而是你不需要case 语句。

案例语句是使对象膨胀的方法。当你使用它时,你正在降低维护。那时你将拥有你想要的所有可能性,但是当你想添加一些东西时,当你不再记得那个对象的责任的微妙之处时,你将不得不审查讨厌的代码,所以你会膨胀它更。

在很短的时间内,它们看起来很友好,但案例陈述不是你的朋友。从长远来看,它们会咬你。

它们还使您的代码不那么灵活。例如,您不能自信地添加关于前面代码的案例。当您不再记得为什么要这样编码时,您将被迫查看旧代码。

案例陈述是好代码的敌人。

如果您有超出 ifTrue:ifFalse: 的内容,那么正确的做法是为此创建状态。所以你要做的是实现三个非常简单的类,它们都理解一些动词。

说,#doTheNextThing。因此,当对象接收到它委托给状态的消息时(无论是这 3 个(或 30 个,因此请注意这很好地扩展了复杂性)中的一个),并且状态知道如何使原始接收者做出正确的反应。

这将使您的代码轻巧、明显且高度可维护。您将能够忘记这一点,因为您知道,当您再次查看它时,一切都非常明显,您无需考虑代码的过去,而是考虑代码的未来。

这很重要,因为您的内存是您拥有的最昂贵的内存,而 AFAIK 不可升级。所以这种技术可以让你做更强大的事情。

此外,对某些人来说,制作 3 个课程可能听起来像是更多的工作,但事实并非如此。任何菜鸟都可以在眨眼间添加 3 个空类,但只有正确的专家会记得旧代码中的 case 语句是如何按照其制作方式制作的。如果你非常乐观,需要几分钟的时间才能回忆起这一点,所以你们都知道下一步该做什么。考虑一下。

于 2010-10-24T12:02:02.583 回答