scala - 值类、通用特征和实例化的必要性

标签 scala value-class universal-trait

specification of value classes ,它说:

A value class can only extend universal traits and cannot be extended itself. A universal trait is a trait that extends Any, only has defs as members, and does no initialization. Universal traits allow basic inheritance of methods for value classes, but they incur the overhead of allocation. For example

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)

这些会导致实例化吗?

最佳答案

Am I correct?

不,如果我们使用 -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 类作为另一种类型”。

虽然调用被分派(dispatch)到静态方法调用:

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)

这对于您的两个示例现在都有效,因为不需要在创建的接口(interface)上进行任何动态调度。

关于scala - 值类、通用特征和实例化的必要性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47140707/

相关文章:

scala - 匹配 Akka 中的值类

Scala值类,用例

scala - Scala 中模拟函数无​​法正确返回值类

scala - 如何从Typesafe config配置系统属性或回退配置变量?

java - 从不同的 gradle 模块导入类

scala - 在 Scala 中定义一个函数,该函数采用通配符数组作为参数

scala - Scala 2.8 中是否有 do-until(后置条件)循环?