为什么在Scala中用默认值实例化trait是一个编译错误?

为什么在Scala中用默认值实例化trait是一个编译错误?,scala,Scala,可通过编译以下代码再现该错误: object ReproducingMyError { trait MyTrait[X] { def someFunc: X } def f[X] = new MyTrait[X] { var x: X = _ def someFunc: X = x } } 生成了2条错误消息。两者都指向 def f[X] = new MyTrait[X] { ^ 消息类似: 错误:结构优化中

可通过编译以下代码再现该错误:

object ReproducingMyError {

  trait MyTrait[X] {
    def someFunc: X
  }

  def f[X] = new MyTrait[X] {
    var x: X = _
    def someFunc: X = x
  }

}
生成了2条错误消息。两者都指向

  def f[X] = new MyTrait[X] {
                 ^
消息类似:

错误:结构优化中的参数类型不能引用在该优化之外定义的抽象类型

错误:结构优化中的参数类型不能引用该优化的类型成员


为什么这是一个编译错误?

如果您不需要在外部公开
var
(我假设您不需要),那么添加显式返回类型可以解决问题:

def f[X]: MyTrait[X] = new MyTrait[X] {
  var x: X = _
  def someFunc: X = x
}
如果没有明确的类型归属,编译器将推断出有问题的“结构精化”,即一个如下所示的类型:
MyTrait[X]{var X:X}

另一种解决方法是将var声明为
private
——这样外部的任何人都看不到它,因此,它不会包含在推断的细化类型中

def f[X] = new MyTrait[X] {
  private var x: X = _
  def someFunc: X = x
}

需要明确的是,问题出在setter上,
def x_=(x:x)
。这就是错误中的参数。