如何正确实现Ordered

时间:2017-01-24 10:14:25

标签: scala

我有一个特质

trait Weight  {
    def getWeight: Int
}

多个类继承它,例如:

case class Test(n: Int) extends Weight  {
  override def getWeight: Int = n
}

现在我想为所有Weight子类添加排序功能。我将Ordered添加到Weight

trait Weight extends Ordered[Weight] {

  def getWeight: Int

  override def compare(that: Weight): Int = this.getWeight.compareTo(that.getWeight)
}

尝试排序:

val seq = Seq(Test(1), Test(4), Test(3), Test(2))

seq.sorted // error

它没有编译:

  

错误:(74,6)分散了类型的隐式扩展   scala.math.Ordering [A $ A254.this.Test]以方法$ conforms开头   在对象Predef中seq.sorted;}       ^

我做错了什么?

2 个答案:

答案 0 :(得分:2)

另一种与mdm略有不同的解决方案。由于sorted隐含Ordering,因此您可以执行以下操作:

seq.sorted(Ordering[Weight])

答案 1 :(得分:1)

您的解决方案不起作用,因为Ordered[T]中的T不变,这意味着Ordered[Weight]Ordered[A]没有任何关系。您需要在子类中指定它。

您可以使用隐式Ordering而不是Ordered

trait Weight{
  def getWeight : Int
}

object Weight{
  implicit def ordering[T <: Weight] : Ordering[T] = Ordering.by(w => w.getWeight)
}
  case class A(w : Int) extends Weight{
  def getWeight = w
}
case class B(w : Int) extends Weight{
  def getWeight = w
}

import Weight._

Seq(A(1),B(2),B(0),A(3),A(-3)).sorted 

将导致:

List(A(-3), B(0), A(1), B(2), A(3))

请注意,此解决方案依赖于Ordering[Int]可用(默认情况下)。