简体   繁体   English

为什么 Scala 特征不允许构造函数参数?

[英]Why don't Scala traits allow constructor parameters?

I'm new to Scala, coming from Java, and I was just reading about traits.我是 Scala 的新手,来自 Java,我只是在阅读 traits。 One thing that gets mentioned often is that traits don't (can't? won't?) have constructor parameters.经常提到的一件事是特征没有(不能?不会?)具有构造函数参数。 I was curious to know if there was a reason for this.我很想知道这是否有原因。

Coming from a long ago maths/computer-science background I was was wondering if this was an inevitable consequence because of some language design decision, or if it was a conscious decision to avoid some inheritance/mix-in problem or another?来自很久以前的数学/计算机科学背景,我想知道这是否是由于某些语言设计决定而不可避免的结果,或者这是否是避免某些继承/混合问题或其他问题的有意识决定?

Was hoping someone might know because it feels like there might be something interesting behind the fact.希望有人知道,因为感觉背后可能有一些有趣的东西。

The other answers describe the language;其他答案描述了语言; I suspect your question may really be "why is it designed in this way".我怀疑您的问题可能真的是“为什么要这样设计”。

I believe it arises out of the awkwardnesses and verboseness that would arise when extending multiple traits, especially with overrides and with types, and various mix-in strategies.我相信它源于扩展多个特征时会出现的笨拙和冗长,特别是使用覆盖和类型以及各种混合策略。

The Cake Pattern often results in various traits providing missing bits to each other in a way that is totally invisible - by design - in the mixing class.蛋糕模式通常会导致各种特征以一种在混合类中完全不可见的方式相互提供缺失的位 - 按照设计 - 。 And mixing can be bi-directional, using self-types .混合可以是双向的,使用self 类型 So the construction of a class from traits can be a very messy business for the compiler.因此,从特征构造类对于编译器来说可能是一件非常麻烦的事情。 Scala often trades simplicity of compiler design and implementation for simplicity of language use and code reduction, and this is certainly a good example. Scala 经常用编译器设计和实现的简单性来换取语言使用和代码缩减的简单性,这当然是一个很好的例子。

So while there may be simple, hierarchical cases where having a constructor might be useful and sufficient, it would almost certainly have to be redundant of other mechanisms for more difficult, non-hierarchical scenarios.因此,虽然可能存在简单的、分层的情况,其中构造函数可能有用且足够,但对于更困难的、非分层的场景,它几乎肯定必须是其他机制的冗余。

Scala 3 will allow trait parameters. Scala 3 将允许特征参数。 Here's a sample from the docs这是文档中的示例

trait Greeting(val name: String) {
  def msg = s"How are you, $name"
}

class C extends Greeting("Bob") {
  println(msg)
}

The answer is: that's what Scala is right now.答案是:这就是 Scala 现在的样子。

But that might not be the case in the future: trait parameters can replace early initializers.但在未来可能不是这样:特征参数可以取代早期的初始化器。 (see Martin Odersky's recent Scala Days presentation page 34) Scala: Where It Came From & Where It is Going (请参阅 Martin Odersky 最近的Scala Days演讲第 34 页) Scala:它从何而来,将向何处去

Traits don't have constructor parameters because traits cannot be constructed.特征没有构造函数参数,因为特征不能被构造。 Given any trait T it's not possible to instantiate any object of type exactly T .给定任何特征T都不可能实例化任何类型为T对象。 You can override trait defs with vals though, so你可以用 vals 覆盖 trait defs,所以

trait Foo {
  def bar: String
}
class Baz(override val bar: String) extends Foo

You can't construct them directly because new MyTrait {} is actually sugar for an anonymous class of new Object with MyTrait {}您不能直接构造它们,因为new MyTrait {}实际上是new Object with MyTrait {}的匿名new Object with MyTrait {}类的糖

Scala 3 allows traits with parameters , just like classes have parameters. Scala 3 允许带有参数的特征,就像类有参数一样。

Trait is analog for Java Interface. Trait 是 Java Interface 的模拟。 The main difference is that trait can have default implementation for their methods.主要区别在于 trait 可以为它们的方法默认实现。

So Java interfaces can't have constructor so do Scala traits所以 Java 接口不能有构造函数,Scala 特征也是如此

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

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