使用特征初始化匿名类

Bos*_*osh 22 inheritance scala initialization class traits

有人可以帮我理解以下行为吗?

简单地说:以下两种情况之间有什么区别...

我定义了一个简单的类c+特征t

scala> class c {val x=true; val y=this.x} 
defined class c

scala> trait t {}
defined trait t
Run Code Online (Sandbox Code Playgroud)

我可以实例化一个新的"c with t"

scala> new c with t
res32: c with t = $anon$1@604f1a67
Run Code Online (Sandbox Code Playgroud)

但我无法用t实例化一个新的"[与c一样的匿名类]"

scala> new {val x=true; val y=this.x} with t
<console>:9: error: type mismatch;
 found   : type
 required: ?{def x: ?}
<console>:9: error: value x is not a member of object $iw
              new {val x=true; val y=this.x} with t
Run Code Online (Sandbox Code Playgroud)

这两种情况有什么区别?

谢谢!

Kri*_*ala 27

这就是你所追求的:

new t {val x=true; val y=this.x}
Run Code Online (Sandbox Code Playgroud)

如果你有另一个特点u {},你可以写new t with u {val x=true; val y=this.x}


Lui*_*hys 5

你偶然发现了"早期定义"语法(更多信息).

查看语言规范的5.1.6节:

早期定义在范围内进行类型检查和评估,该范围在定义模板之前有效,由封闭类的任何类型参数以及在定义的模型之前的任何早期定义进行扩充.特别是,this 在早期定义的右侧的任何引用都指的this是模板外部的身份.因此,早期定义不可能是指由模板构造的对象,或者指的是其中一个字段和方法,除了同一部分中的任何其他前面的早期定义.

在你的情况下问题是this.x.如果你用just替换它x,所以你指的是上面最后一句中提到的"前面的早期定义"(谢谢,@ som-snytt!),它会编译.

当然,你可能不打算写一个早期的初始化程序,所以根据Kristian Domagala的答案写一下.