2014-10-19 84 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