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

scala – 如何在没有间接费用的情况下丰富价值类?

发布时间:2020-12-16 09:17:56 所属栏目:安全 来源:网络整理
导读:Scala 2.10引入了值类,您可以通过使您的类扩展AnyVal来指定.价值类别有很多限制,但是他们的巨大优势之一是允许扩展方法,而不会造成新类别的惩罚:除非需要进行拳击.要把值类放在一个数组中,它只不过是一个旧类加上一组把这个类作为第一个参数的方法.从而, im
Scala 2.10引入了值类,您可以通过使您的类扩展AnyVal来指定.价值类别有很多限制,但是他们的巨大优势之一是允许扩展方法,而不会造成新类别的惩罚:除非需要进行拳击.要把值类放在一个数组中,它只不过是一个旧类加上一组把这个类作为第一个参数的方法.从而,

implicit class Foo(val i: Int) extends AnyVal {
  def +*(j: Int) = i + j*j
}

解开一些可以不比编写我自己的j $j更贵的东西(一旦JVM包含方法调用).

不幸的是,SIP-15中描述价值类的限制之一是

  1. The underlying type of C may not be a value class.

如果你有一个价值类,你可以让你的手,说,作为一种方式提供类型安全的单位没有拳击的开销(除非你真的需要):

class Meter(val meters: Double) extends AnyVal {
  def centimeters = meters*100.0                // No longer type-safe
  def +(m: Meter) = new Meter(meters+m.meters)  // Only works with Meter!
}

那么有没有一种可以丰富Meter的方法呢? SIP-15的限制防范明显

implicit class RichMeter(m: Meter) extends AnyVal { ... }

做法.

解决方法

为了扩展值类,需要重新获取底层类型.由于价值类需要使其包装类型可访问(我不仅仅是我上面的),你可以随时做到这一点.您不能使用方便的隐式类快捷方式,但您仍然可以添加隐式转换longhand.所以,如果你想添加一个方法到米,你必须做一些类似的

class RichMeter(val meters: Double) extends AnyVal {
  def -(m: Meter) = new Meter(meters - m.meters)
}
implicit def EnrichMeters(m: Meter) = new RichMeter(m.meters)

还要注意,允许(自由)使用原始值类重新包装任何参数,因此如果它具有您所依赖的功能(例如,它包装一个Long但执行复杂的位混合),则只需重新打包基础类你想要扩展的价值类,无论你需要什么.

(另请注意,除非您导入language.implicitConversions,否则您会收到警告.)

附录:在Scala 2.11中,您可以私下使用;对于这样做的情况,您将无法使用这个技巧.

(编辑:李大同)

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

    推荐文章
      热点阅读