【问题标题】:Scala generics: How to declare that a type must be a case class?Scala泛型:如何声明一个类型必须是一个案例类?
【发布时间】:2015-10-29 23:03:36
【问题描述】:

我有几个带有count 字段的案例类。默认情况下它是 1,我的代码中有一个减少,它对重复项进行分组并将该值求和以找到每个对象的数量。例如:

case class Person(name: String, count = 1)
personList.groupBy(_.name).reduce((x,y) => x.copy(count = x.count + 1))

我在几个案例类中都有这个逻辑,由于我的逻辑比上面的例子复杂一点,我想创建一个通用的合并函数。

所以我创建了一个带有count 字段的sealed trait。然后我改变了我的案例类以扩展它,例如:

case class Person(name: String, override val count) extends Countable

到目前为止,一切都很好。

但是,我不知道如何声明我的 merge 函数,以便它只接受扩展 Countable 的案例类。因此,它找不到copy 方法。

这是我所拥有的:

  def merge[T <: Countable](f: T => Seq[String])(ms: Seq[T]): Vector[T] = 
    ms.groupBy(x => f(x).mkString("_")).mapValues(_.reduce { (x,y) => 
     x.copy(count = x.count + 1)        // can't find `copy`
  }).values.toVector

是否有一个类型类我也可以包含,这意味着一个类型有一个使用 Scala 2.11.7 的 copy 方法(或者是一个案例类)?

更新:

Countable 特征是:

sealed trait Countable {

  def timesSeen: Long = 1
}

【问题讨论】:

    标签: scala generics


    【解决方案1】:

    你是如何定义你的可数特质的。 以下 sn-p 对我来说很好:

      trait Countable[Z] {
        def count: Int
        def copy: Z
      }
    
      case class Person(name: String, override val count: Int) extends Countable[Person] {
        override def copy: Person = this
      }
    
      def merge[T <: Countable[T]](f: T => Seq[String])(ms: Seq[T]): Vector[T] = {
        val r = ms.groupBy(x => f(x).mkString("_")).mapValues(_.reduce { (x, y) =>
          x.copy
        }).values.toVector
        r
      }
    

    【讨论】:

    • 您如何声明使用该特征的案例类?我遇到语法错误。
    • 不仅仅是x.copy,而是x.copy(count = x.count + 1)。现在我根本无法参数化copy...
    • 啊,我想我明白了。
    • 我也有同样的问题,如何定义一个抽象类型的copy()方法,可以像案例类复制方法一样参数化,我还是不知道怎么做?跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-02
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多