使用特征初始化匿名类

时间:2013-08-13 21:57:41

标签: class scala inheritance initialization traits

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

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

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

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

scala> trait t {}
defined trait t

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

scala> new c with t
res32: c with t = $anon$1@604f1a67

但是我不能用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

这两种情况有什么区别?

谢谢!

2 个答案:

答案 0 :(得分:25)

这就是你所追求的:

new t {val x=true; val y=this.x}

如果您有其他特征u {},则可以写new t with u {val x=true; val y=this.x}

答案 1 :(得分:5)

你偶然发现了“早期定义”语法(more info)。

查看语言规范的第5.1.6节:

  

对早期定义进行类型检查并在范围内进行评估   在定义模板之前生效,由任何扩充   封闭类的类型参数和任何早期定义   在被定义的那个之前。特别是对this的任何引用   在早期定义的右侧是指身份   仅在模板外部的this因此,这是不可能的   早期的定义是指由人构建的对象   模板,或指其中一个字段和方法,除了any   同一部分中的其他前面的早期定义。

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

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