【问题标题】:Scala Implicit OrderingScala 隐式排序
【发布时间】:2014-11-02 05:48:28
【问题描述】:

我有没有办法为两个不同的类定义相同的隐式排序?

我尝试按照以下几行做一些事情,但它没有检测到排序。

abstract class Common
case class A extends Common
case class B extends Common

implicit val KeyOrdering = new Ordering[Common] {
    override def compare(x: Common, y: Common): Int = {
      x.toString.compareTo(y.toString)
   }
}

【问题讨论】:

  • extends 是保留关键字而不是类型。你的意思是Common
  • 是的,我就是这个意思。感谢您指出这一点。
  • 是的,我也不确定为什么这不起作用。 List(A(), B()).sorted 表示找不到隐式排序,但明确的 List(A(), B()).sorted(KeyOrdering) 有效。

标签: scala implicit


【解决方案1】:

正如@ntn 所指出的,您的列表的推断类型(其两个元素的最小上限)是Product with Serializable with Common。由于scala.Ordering 的类型参数不是逆变的,因此隐式解析失败,因为它不持有Ordering[Common] <: Ordering[Product with Serializable with Common]

您可以通过编写隐式排序来解决此问题,以便它始终具有正在考虑的隐式参数的确切类型:

abstract class Common
case class A() extends Common
case class B() extends Common

object Common {
  implicit def ordering[A <: Common]: Ordering[A] = new Ordering[A] {
    override def compare(x: A, y: A): Int = {
      x.toString.compareTo(y.toString)
    }
  }
}

或者为了简洁:

object Common {
  implicit def ordering[A <: Common]: Ordering[A] = Ordering.by(_.toString)
}

【讨论】:

【解决方案2】:

如果您删除 A 和 B 的案例类(或者甚至只删除其中一个),那么它可以工作。 对于List(A(), B()).sorted,它无法找到Product with Serializable with COrdering,因为A 和B 的基类是带有C 的Product(因为A 和B 都是case 类)。

如果您要创建一个包含两种不同基本类型的元素的列表,我假设您想要一个 List[C] 类型的列表,您可以在其中声明元素,然后再使用它们(或从返回类型 @ 的某个函数中获取它们) 987654325@.

val a: C = A()
val b: C = B()
List(a,b).sorted

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 2021-05-17
    • 2018-08-16
    • 2020-12-08
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多