有人最近告诉我,Scala的特征不是“真实”的特征,而且他们真的只是混合。不幸的是,我没有机会问他为什么。有没有人知道他的意思?
修改 作为“特征”的定义,我指的是NathanaelSchärli的dissertation and concept paper引入的特征。大多数mixin和/或多继承实现似乎缺少的一个关键特性是在导入方法时重命名方法以避免冲突/模糊。 Scala能做到吗?
答案 0 :(得分:9)
我认为这可能与Scala中的内容有关,而不是原始paper中提出的内容。
我曾经考虑过这个问题,除了实现差异之外,我得出结论,Scala中的特性确实留下了一些不足之处。 Scala让你编写但不排除方法的方式很奇怪。为了避免冲突,它从其他语言中借用了一种称为方法解析顺序(或Scala-speak中的线性化)的东西。对于支持多重继承的语言而言,存在一个众所周知的问题,我将大胆地将Scala归类为该组的成员。问题在于理解它太复杂和耗时。
Scala的方法解析顺序是一个奇怪的野兽,它有自己的方法调度算法。它不是Dylan的C3,它在Python中使用,有一些值得注意的problems,但它具有与之相关的所有问题。更糟糕的是,我可以通过调用它的.mro()
方法来查找Python对象的MRO。 Scala中没有相应的内容。
我可以告诉你,每次我需要查找解决方法的地方时,我都不太喜欢在脑子里运行Scala MRO算法。
答案 1 :(得分:2)
mixins和traits之间的一个关键是mixins有字段,而traits没有。从原始论文中解释,一个特点:
乍一看,第三点似乎在Scala实现中被破坏了。但是,traits只能访问受隐式getter和setter保护的公共字段。本文接着描述了这对于特征的实现是可以接受的。
您指出特征的一个关键特征是导入时可以重命名方法。考虑到JVM的限制,这是不可能的。关于这一点的连贯讨论可以在这里找到:http://scala-programming-language.1934581.n4.nabble.com/Trait-method-aliasing-td2322026.html,特别是David Pollak的帖子。
最后,我对你的一般问题的回答是“有点”。详细说明,虽然Scala特征并不是本文所定义的严格特征,但它们也不是严格意义上的混合。无论哪种方式,最好使用它们,就像它们的特性一样,并遵守它们的设计原则。
答案 2 :(得分:1)
不,Scala无法在导入时重命名。
我想知道这是怎么回事。如果将特征m
的方法T
重命名为对象m2
中的o
,如果p.m
是类型参数,将如何解析p
T
和o
已通过它了吗?