2010-01-28 124 views
2

我有一段代碼,我用它來提供一個優先級隊列的順序隱:在這個Scala代碼中,compareTo與compareTo有什麼不同?

type Time = Int 
type Item = (Time, Whatever) 

implicit def order(thisItem: Item): Ordered[Item] = 
    new Ordered[Item] { 
     override def compare(thatItem: Item) = { 
     val result = thisItem._1 compareTo thatItem._1 
     -result 
     } 
    } 

下面這段代碼上的Scala 2.7無法編譯 - 錯誤信息是:

error: type mismatch; 
found : SimulationMode.this.Time 
required: ?{val compareTo: ?} 
Note that implicit conversions are not applicable because they are ambiguous: 
both method int2Integer in object Predef of type (Int)java.lang.Integer 
and method intWrapper in object Predef of type (Int)scala.runtime.RichInt 
are possible conversion functions from SimulationMode.this.Time to ?{val compareTo: ?} 
     val result = thisItem._1 compareTo thatItem._1 
          ^

我發現了兩個辦法讓它編譯 - 要麼宣佈是詮釋結果的類型或改變使用compareTo比較。但我的問題是 - 是否有這樣一個錯誤的原因,這個消息意味着什麼,這是一個在scala編譯器中的錯誤? compareTo只調用Ordered [A]特徵中的比較,並且具有相同的特徵...再加上它們都返回Int,那麼爲什麼我自己聲明類型是重要的?

回答

4

發生這種情況是因爲Int沒有compareTo方法,就像錯誤說的那樣。此外,當搜索隱式使得這項工作時,編譯器發現在轉換爲java.lang.Integerscala.runtime.RichInt之間的模糊性,兩者都提供compareTo方法。當您使用compare而不是compareTo時,它可以工作,因爲只有RichInt轉換提供了該方法。 FYI compare來自斯卡拉的Ordered特質。

我不確定當你聲明結果的類型時它的工作原理是什麼,這應該沒有什麼區別,你必須發佈你正在使用的代碼似乎使它工作。

1

錯誤來自Scala和Java中原始整數的不同裝箱。我很難確切地說出你的代碼在做什麼 - 什麼類型的是thisItem._1?這是一個原始的整數?

無論如何,在java.lang.Integerscala.runtime.RichInt(分別爲Java和Scala的盒裝整數)上都定義了compareTo方法。比較僅在scala.runtime.RichInt上定義。所以當你使用比較時,這是一個明確的要求;與compareTo,它不知道使用哪個拳擊。

2

我想補充到雷克斯的和傑夫的答案只有一個切實可行的意見如何處理歧義是使用類型歸屬:

val result = (thisItem._1: Integer) compareTo (thatItem._1: Integer) 

不管怎樣,在這種情況下使用比較可能是因爲你是最好的解決辦法依靠Scala的類型。