24

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

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

我定义了一个简单的类c+特征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

这两种情况有什么区别?

谢谢!

4

2 回答 2

29

这是你所追求的:

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

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

于 2013-08-13T23:05:18.997 回答
5

您偶然发现了“早期定义”语法(更多信息)。

查看语言规范的第 5.1.6 节:

早期定义在定义模板之前有效的范围内进行类型检查和评估,并通过封闭类的任何类型参数和任何在定义之前的早期定义进行扩充。特别是,this 早期定义右侧的任何引用都是指this模板外部的标识。因此,早期定义不可能引用模板构造的对象,或者引用其字段和方法之一,除非同一节中的任何其他早期定义。

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

当然,您可能不打算编写早期初始化程序,因此只需按照 Kristian Domagala 的回答编写即可。

于 2013-08-13T23:25:16.967 回答