【问题标题】:Early initializer `new {} with SomeTrait` fails带有 SomeTrait 的早期初始化程序 `new {} 失败
【发布时间】:2016-12-16 17:19:01
【问题描述】:

使用早期初始化语法时似乎有些微妙之处。

trait Base { def callMe = "callMe" }
trait Proxy { this: Base => def call = s"proxied: $callMe" }

val base1 = new Base { }   // non-early init works
val baseFail = new { } with Base   // error: trait Base is abstract; cannot be instantiated
val base2 = new { val n=1 } with Base   // why does this fix the failure?
val proxy = new { } with Base with Proxy   // why doesn't this fail?

为什么baseFail 行失败,而其他vals 行却没有?

错误信息也令人困惑——我不是要实例化Base,只是把它混进去。

【问题讨论】:

    标签: scala traits anonymous-class


    【解决方案1】:

    当您编写new { } with Base 时,技术上没有任何早期定义。根据 SLS 5.1.6,编译器会寻找这样的模式:

    EarlyDefs         ::= `{' [EarlyDef {semi EarlyDef}] `}' `with'
    EarlyDef          ::=  {Annotation} {Modifier} PatVarDef
    

    虽然它没有明确说明当定义序列为空时会发生什么,但它似乎只是将它们删除,因为当你编译val a = new { val x = 1 } with Base时,在解析阶段之后你会得到这样的东西:

    val a = {
      final class $anon extends Base {
        val x = _;
        def <init>() = {
          val x = 1;
          super.<init>();
          ()
        }
      };
      new $anon()
    }
    

    但如果你清空大括号,你会得到:

     val a = new Base()
    

    这是非法的,new Base 也是如此。


    总结一下:

    是一个匿名类,是允许的 :

    val base1 = new Base { }
    

    简化为new Base,这是非法的:

    val baseFail = new { } with Base
    

    是一个适当的早期定义(非空),这是允许的:

    val base2 = new { val n=1 } with Base
    

    简化为new Base with Proxy,这也是允许的:

    val proxy = new { } with Base with Proxy
    

    new { } with Base { } 也可以编译,但它和new Base { } 完全一样,所以没有理由这样写。

    【讨论】:

      【解决方案2】:

      我不确定,但对于这种行为,我能想到的最简单的解释是空的早期初始化程序被简单地优化掉了,所以它相当于 val baseFail = new Baseval proxy = new Base with Proxynew Base 失败并显示相同的错误消息,new Base with Proxy 是合法的,因为它是一个匿名类。如果是这样,我认为这在技术上是一个编译器错误,但相当轻微。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-08
        • 2012-09-04
        • 2012-09-10
        • 2011-10-15
        • 2014-05-30
        • 2011-07-11
        相关资源
        最近更新 更多