2014-10-19 81 views
2

我正在尝试为不同但相似类别的对象定义自然排序。在Java中,我将使用Comparable,看起来在Scala中执行等效的方法是使用Ordered。我有以下特点:Scala中的有序特征的问题

trait Positioned extends Ordered[Positioned] { 
    def position: Int = 1 

    override def compare(that: Positioned): Int = position - that.position 
} 

我想这个特点适用于多种情况下的类像这样的:

case class Image(id: String, 
       override val position: Int = 1) extends Positioned 

这符合得很好,但在运行时,当我打电话sorted对这些集合Image对象,我得到这个错误:

diverging implicit expansion for type scala.math.Ordering[com.myapp.Image] 
starting with method $conforms in object Predef 

请让我知道这意味着什么和我能做什么来解决它。

+0

也许这与[SI-8541(https://开头issues.scala-lang.org/browse/SI-8541)? – 2014-10-19 02:02:29

+0

我也看到了,很可能。但由于案件有些差异可能很大,我仍然认为我会问。有了Scala的所有编译魔法,我很难找出问题所在。 – Vidya 2014-10-19 02:29:24

+0

顺便说一句,略有偏离主题,但如果有任何溢出的机会,在比较方法中减法是不正确的。返回'position.compare(that.position)'会更安全,速度稍慢。 – Nate 2014-10-21 02:44:06

回答

2

您绝对可以做你想做什么:

trait Positioned[T <: Positioned[T]] extends Ordered[T] { 
    def position: Int = 1 

    override def compare(that: T): Int = position - that.position 
} 

case class Image(id: String, override val position: Int = 1) extends Positioned[Image] 

里面Scala的REPL的:

scala> val imgs = Seq(Image("5", 5), Image("4", 4), Image("1", 1), Image("3", 3)) 
imgs: Seq[Image] = List(Image(5,5), Image(4,4),Image(1,1), Image(3,3)) 

scala> imgs.sorted 
res1: Seq[Image] = List(Image(1,1), Image(3,3), Image(4,4), Image(5,5)) 
+0

为什么这个工作,当'特性定位扩展有序[定位]'不? – 2016-05-05 22:36:52

+0

此外,这不会让您比较'图像'实例与'定位'的其他子类的实例。 – 2016-05-05 22:38:21

+1

@DavidMoles它可以工作,但你必须调用'imgs.sorted [Positioned]' - 这将允许你排序任何子类'定位'的东西。我想,我不清楚人们是否希望定位的子类是可排序的。 – Nate 2016-05-07 16:56:57