scala – 值类,普遍特征和实例化的必要性
在
specification of value classes,它说:
trait Printable extends Any { def print(): Unit = println(this) } class Wrapper(val underlying: Int) extends AnyVal with Printable val w = new Wrapper(3) w.print() // actually requires instantiating a Wrapper instance 第一个问题 现在,我认为这意味着以下(可能)不需要实例化: trait Marker extends Any class Wrapper(val underlying: Int) extends AnyVal with Marker { def print(): Unit = println(this) //unrelated to Marker } val w = new Wrapper(3) w.print() //probably no instantiation as print is unrelated to Marker 我对么? 第二个问题 而且我认为这是否需要实例化是偶然的: trait Printable extends Any { def print(): Unit //no implementation } class Wrapper(val underlying: Int) extends AnyVal with Printable { override def print() = println(this) //moved impl to value class } val w = new Wrapper(3) w.print() // possibly requires instantiation 在概率平衡上,我也认为不需要实例化 – 我是否正确? 编辑 我没有想过示例中print()的确切实现: def print(): Unit = println(this) 假设我使用以下代码: def print(): Unit = println(underlying) 这会导致实例化吗? 解决方法
不,如果我们使用-Xprint:jvm发出最终编译输出,我们可以看到它: <synthetic> object F$Wrapper extends Object { final def print$extension($this: Int): Unit = scala.Predef.println(new com.testing.F$Wrapper($this)); 这是因为println有一个需要Any的类型签名,所以我们在这里拍摄自己,因为我们有效地“将值类ttpe视为另一种类型”. 虽然调用被调度到静态方法调用: val w: Int = 3; F$Wrapper.print$extension(w) 我们仍然在print $extension内部进行分配. 如果我们偏离使用Wrapper.this,那么你的第一个假设确实是正确的,我们可以看到编译器愉快地打开Wrapper: <synthetic> object F$Wrapper extends Object { final def print$extension($this: Int): Unit = scala.Predef.println(scala.Int.box($this)); 呼叫站点现在看起来像这样: val w: Int = 3; com.testing.F$Wrapper.print$extension(w) 这对于您的两个示例现在都有效,因为在创建的接口上不需要任何动态分派. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |