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

定义要在scala中按案例类扩展的特征

发布时间:2020-12-16 08:50:21 所属栏目:安全 来源:网络整理
导读:我有一些case类,它的伴随对象中定义了一个方法元组.从下面的代码对象中可以看出,它只是代码重复. case class Book(id: Int,isbn: String,name: String)object Book { def tupled = (Book.apply _).tupled // Duplication}case class Author(id: Int,name: St
我有一些case类,它的伴随对象中定义了一个方法元组.从下面的代码对象中可以看出,它只是代码重复.

case class Book(id: Int,isbn: String,name: String)

object Book {
  def tupled = (Book.apply _).tupled // Duplication
}


case class Author(id: Int,name: String)

object Author {
  def tupled = (Author.apply _).tupled // Duplication
}

从另一个问题(can a scala self type enforce a case class type),似乎我们不能强制将特征的自我类型作为案例类.

有没有办法定义一个可以应用如下的特征(比如Tupled)?

// What would be value of ???
trait Tupled {
  self: ??? =>

  def tupled = (self.apply _).tupled
}

// Such that I can replace tupled definition with Trait
object Book extends Tupled {
}

解决方法

因为Scala中的FunctionN类型之间没有关系,所以如果没有arity级别的样板,就不可能做到这一点 – 在没有列举所有可能的成员数量的情况下,没有办法抽象出伴随对象的apply方法.

你可以用一堆CompanionN [A,B,C,…]特性手工完成,但这很烦人. Shapeless提供了一个更好的解决方案,允许您编写如下内容:

import shapeless.{ Generic,HList },shapeless.ops.product.ToHList

class CaseClassCompanion[C] {
  def tupled[P <: Product,R <: HList](p: P)(implicit
    gen: Generic.Aux[C,R],toR: ToHList.Aux[P,R]
  ): C = gen.from(toR(p))
}

然后:

case class Book(id: Int,name: String)
object Book extends CaseClassCompanion[Book]

case class Author(id: Int,name: String)
object Author extends CaseClassCompanion[Author]

您可以这样使用:

scala> Book.tupled((0,"some ISBN","some name"))
res0: Book = Book(0,some ISBN,some name)

scala> Author.tupled((0,"some name"))
res1: Author = Author(0,some name)

您甚至可能不想要CaseClassCompanion部分,因为可以构造一个将元组转换为案例类的通用方法(假设成员类型对齐):

class PartiallyAppliedProductToCc[C] {
  def apply[P <: Product,R]
  ): C = gen.from(toR(p))
}

def productToCc[C]: PartiallyAppliedProductToCc[C] =
  new PartiallyAppliedProductToCc[C]

然后:

scala> productToCc[Book]((0,"some name"))
res2: Book = Book(0,some name)

scala> productToCc[Author]((0,"some name"))
res3: Author = Author(0,some name)

这适用于最多包含22个成员的案例类(因为如果有超过22个参数,则无法将伴随对象上的apply方法扩展为函数).

(编辑:李大同)

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

    推荐文章
      热点阅读