scala 使用特征初始化匿名类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18219922/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 05:34:58  来源:igfitidea点击:

Initializing an anonymous class with a trait

classscalainheritanceinitializationtraits

提问by Bosh

Can someone help me understand the following behavior?

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

Simply put: what is the difference between the following two cases where...

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

I define a simple class c+ trait t

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

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

scala> trait t {}
defined trait t

I can instantiate a new "c with t"

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

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

But I can't instantiate a new "[anonymous class just like c] with t"

但我无法实例化一个新的“[匿名类就像 c] 与 t”

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

What's the difference between these two cases?

这两种情况有什么区别?

Thanks!

谢谢!

采纳答案by Luigi Plinge

You've stumbled on "early definition" syntax (more info).

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

Check out section 5.1.6 of the language specification:

查看语言规范的第 5.1.6 节:

An early definition is type-checked and evaluated in the scope which is in effect just before the template being defined, augmented by any type parameters of the enclosing class and by any early definitions preceding the one being defined. In particular, any reference to thisin the right-hand side of an early definition refers to the identity of thisjust outside the template. Consequently, it is impossible that an early definition refers to the object being constructed by the template, or refers to one of its fields and methods, except for any other preceding early definition in the same section.

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

In your case the problem is with this.x. If you replace it with just x, so you're referring to the "preceding early definition" as mentioned in the last sentence above (thanks, @som-snytt !), it compiles.

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

Of course, you probably didn't intend to write an early initializer, so just write it as per Kristian Domagala's answer.

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

回答by Kristian Domagala

Is this what you're after:

这是你追求的吗:

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

If you have another trait, u {}, you can write new t with u {val x=true; val y=this.x}

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