加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 值类,普遍特征和实例化的必要性

发布时间:2020-12-16 18:37:21 所属栏目:安全 来源:网络整理
导读:在 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 def s as members,and does no initialization. Universal traits al
在 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视为另一种类型”.

虽然调用被调度到静态方法调用:

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)

这对于您的两个示例现在都有效,因为在创建的接口上不需要任何动态分派.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读