2011-08-27 66 views
4

我有采取了類似並返回可比性和包裝另一個是做同樣的事情方法的方法:視圖綁定與上邊界類型綁定不兼容?

def myMethod[T <: Comparable[T]](arg: T): T = otherMethod(arg) 
def otherMethod[T <: Comparable[T]](arg: T): T = arg 

這將編譯,但不會允許我這樣稱呼myMethod的用int或任何其他類型這需要隱式轉換才能實現Comparable。據我瞭解,鑑於界限旨在解決這類問題,但使用結合

def myMethod[T <% Comparable[T]](arg: T): T = otherMethod(arg) 

我得到的編譯器錯誤的觀點:

inferred type arguments [T] do not conform to method otherMethod's type parameter bounds [T <: java.lang.Comparable[T]]

到目前爲止,唯一的解決方法我已經拿出來就是使用第二種類型參數並且在兩者之間施放:

def myMethod[T <% Comparable[T], U <: Comparable[U]](arg: T): T = 
    otherMethod(arg.asInstanceOf[U]).asInstanceOf[T] 

這個很有效,但很醜。有沒有更好的辦法?

回答

6

以下哪項工作?

  1. 使在這兩種方法結合的相一致的T的視圖,

    def otherMethod[T <% Comparable[T]](arg: T): T = arg 
    def myMethod[T <% Comparable[T]](arg: T): T = otherMethod(arg) 
    
  2. 引入新類型參數U <: Comparable[U]和從TU的隱式轉換,

    def otherMethod[T <: Comparable[T]](arg: T): T = arg 
    def myMethod[U <: Comparable[U], T <% U](arg: T): U = otherMethod(arg) 
    

問題與您的版本錫永是T <% Comparable[T]轉換T鍵入Comparable[T],但這並不滿足遞歸型T <: Comparable[T <: Comparable[T <: ...]]),該otherMethod期望。


更新。無論要使用otherMethodmyMethod與Scala的Int,你需要幫助的類型inferencer一點點,

myMethod(2)     // Int value types don't implement Comparable 
myMethod(2: java.lang.Integer) // Apply implicit conversion (Int => java.lang.Integer) 

更新2。在評論中,你說你願意讓myMethod有點醜陋,以改善呼叫站點的類型推斷。這裏有一個方法,

def myMethod[U <: Comparable[U], T](arg: T) 
    (implicit ev1: T => U, ev2: T => Comparable[U]): U = otherMethod(arg) 
myMethod(2) // returns java.lang.Integer(2) 

訣竅是使用兩個隱式轉換:ev1實際上得到應用,並ev2僅在那裏的援助類型推斷。後者要求Scala搜索其含義爲Int => Comparable[U]類型的轉換。在這種情況下,只能找到一個這樣的轉換,修復U = java.lang.Integer。請致電​​。您會看到ev1ev2參數都使用了相同的隱式Predef.int2Integer

旁註:這是最好的避免asInstanceOf蒙上因爲這些失利Scala的類型系統的健全性。

+0

1.不,不幸的是,otherMethod在第三方庫中定義。 2.是!這似乎工作。謝謝! – ethzero

+0

很高興能幫到你:-) –

+0

其實,我說的太快了......第二種解決方案的確可以編譯,但我仍然無法用Int來調用它。這裏是錯誤:「類型參數[Int,Int]不符合方法myMethod的類型參數bounds [U <:java.lang.Comparable [U],T]」 – ethzero