Scala中的特质与包的区别

8
观看完Martin关于Reflection and Compilers的主题演讲后,我似乎无法将这个疯狂的问题排除在脑海之外。马丁谈到了“(Wedding) Cake Pattern”等内容,其中特质起着核心作用。我想知道,既然我们已经有了特质,为什么还需要包?是否有任何一个package可以做到的事情,trait(至少在理论上)不能做到?
我不是在谈论当前的实现,我只是试图想象如果我们用特质替换包会是什么样子。在我的想象中,它会是这样的:
- 减少一个关键字(package是不必要的) - 不需要package object 总结一下我的所有问题:
  1. 理论上是否可能从语言中删除包并改用特征?
  2. 这种改变会带来哪些其他好处?(我在考虑一流包和一流导入,但混合组合是编译时的事情,尽管超级调用是动态绑定的)
  3. Java/JVM兼容性是唯一的障碍吗?

更新

Daniel Spiewak在此主题演讲中谈到依赖注入只是使用Cake Pattern可以做的所有事情的冰山一角。


这只是(静态)新语言而已! :) - Pablo Lalloni
2个回答

7
马丁·奥德斯基(Martin Odersky)表示,Scala 只需要 traits、objects、methods 和 paths(我希望我没有忘记什么)就可以完成所有操作。
类和包只是 Scala 的存在,因为它旨在成为一个主机语言,即一种运行于(这实际上不是有趣的部分)和与主机平台(这是重要的部分)进行交互的语言。Scala 旨在与一些主机平台进行交互,其中包括 Java 平台和 CLI,这两个平台都具有类和包的概念(在 CLI 的情况下是命名空间),这些概念与 traits 或 objects 明显不同,并且不能轻松地用 traits 或 objects 表示。这与接口不同,接口可以轻松地映射到和从纯抽象 traits 进行映射。
以上声明是在讨论有关潜在删除 Scala 中泛型,因为抽象类型也可以实现泛型所能实现的所有内容。

所以你的意思是从理论上讲它确实是可能的,但是没有实现它的价值,因为我们都无法想象它实际上会给我们带来什么好处 ;) - agilesteel
它将大幅简化语言,而简洁性是Scala的主要目标之一,因此这绝对有意义。然而,它将失去主机平台互操作性,这是Scala的另一个主要目标。您可以在所有需要使用包的情况下使用对象,但是没有清晰的方法将Scala对象映射到Java包或CLI命名空间。接口的情况不同:完全抽象特征和接口之间存在明显的映射,因此,Scala可以与Java / CLI接口进行互操作,而无需将它们纳入语言中。 - Jörg W Mittag

6
在Scala中,对象和包几乎具有相同的作用,对象也被称为模块。对象应该被视为模块,因为它们可以包含任何定义,包括其他对象和重要的类型。Trait可以被认为是抽象模块。它可以包含任何定义,任何成员都可以是抽象的,包括重要的类型成员。我重申所有这些只是为了突出对称性。也许与主题无关,但对我来说,特质似乎是Scala中与对象和功能思想融合同样重要的创新。
最终给出答案:
1. 我认为可以通过对象(而不是特质)来删除包。 2. 好处在于简化 - 包对象不需要显式定义。 3. 我认为包与对象在Java / JVM兼容性方面是不同的。
更多评论:在视频中,Martin谈到了特质(抽象模块),而不是具体模块,因为后者仅在最后一刻出现以组装和实现某些抽象模块的组合。
即使不“混合蛋糕”,使用抽象模块也很好。例如,在勾勒出一些代码时,您可能会定义一个模块来包含定义。但是,一旦遇到未准备填写的类型或值,请勿提供诸如null之类的虚拟值。相反,将对象切换为特质并将成员保留为抽象的。

“OT”是什么?另外,有一个很好的???函数,对于那些你还没有准备好编写的实现,它会抛出一个NotImplementedError异常。我相信使用它比对程序进行任何结构更改要方便得多。 - Nikita Volkov
抱歉,OT=离题了。Yep ???可以在“草图”绘制时填充值,虽然它没有类型。 - Arnold deVos
特质在 Scala 之前就被发明了,详见 http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf。 - iwein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接