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

scala – 案例类和特征线性化

发布时间:2020-12-16 21:31:36 所属栏目:安全 来源:网络整理
导读:假设我想写一个case class Stepper,如下所示: case class Stepper(step: Int) {def apply(x: Int) = x + step} 它附带了一个很好的toStringimplementation: scala Stepper(42).toStringres0: String = Stepper(42) 但它并不是一个功能: scala Some(2) map
假设我想写一个case class Stepper,如下所示:

case class Stepper(step: Int) {def apply(x: Int) = x + step}

它附带了一个很好的toStringimplementation:

scala> Stepper(42).toString
res0: String = Stepper(42)

但它并不是一个功能:

scala> Some(2) map Stepper(2)
<console>:10: error: type mismatch;
 found   : Stepper
 required: Int => ?
              Some(2) map Stepper(2)

解决方法是实现“功能特征”

case class Stepper(step: Int) extends (Int => Int) {def apply(x: Int) = x + step}

但是,我不能再有一个很好的toString实现了:

scala> Stepper(42).toString
res2: java.lang.String = <function1>

那么问题是:我可以有这两个世界的最好吗?有没有一个解决方案,我有一个很好的toString实现免费和一个trait功能的实现.换句话说,有没有一种方法来应用线性化,最终应用案例类的语法糖?

解决方法

这个问题不是与线性化有关.在case-classes toString是由编译器自动生成的方法,当且仅当在最终类型中不覆盖Any.toString时.

但是,答案部分与线性化有关 – 我们需要使用由编译器生成的方法来覆盖Function1.toString,如果不是由Function1引入的版本:

trait ProperName extends Product {
  override lazy val toString = scala.runtime.ScalaRunTime._toString(this)
}

// now just mix in ProperName and... magic!
case class Stepper(step: Int) extends (Int => Int) with ProperName {
  def apply(x:Int) = x+step
}

然后

println(Some(2) map Stepper(2))
println(Stepper(2))

会生产

06002

更新

以下是一个不依赖于未记录的API方法的ProperName trait的版本:

trait ProperName extends Product {
  override lazy val toString  = {
    val caseFields = {
       val arity = productArity
       def fields(from: Int): List[Any] =
         if (from == arity) List()
         else productElement(from) :: fields(from + 1)
       fields(0) 
    }
    caseFields.mkString(productPrefix + "(",",")")
  }
}

替代toString实现是从原始_toString方法scala.runtime.ScalaRunTime._toString的源代码派生出来的.

请注意,这个替代实现仍然是基于一个case类总是扩展Product trait的假设.虽然后者与Scala 2.9.0一样,但事实上已被Scala社区的一些成员所了解和依赖,但并没有正式记录为Scala Language Spec的一部分.

(编辑:李大同)

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

    推荐文章
      热点阅读