2010-09-15 41 views
12

我有一個特質,看起來像這樣(一些進一步的信息可以在this related question by myself發現,雖然我不認爲,它需要這個問題)協變Typeparameter斯卡拉需要Java接口

trait Extractor[-A,+B] { 
    def extract(d:A):B 
    //lots of other things 
} 
是不變

要在現有的java框架中使用此功能,我希望這個Extractor具有返回Comparator[B](即java.util.Comparator)或甚至更好地延伸Comparator[A]的函數。現在出現問題,因爲Comparator的類型參數應該是不變的,而A是逆變的,B是協變的。

所以我得到這樣的錯誤:

scala> import java.util.Comparator 
import java.util.Comparator 

scala> trait Extractor[-A,+B] extends Comparator[A] 
<console>:6: error: contravariant type A occurs in invariant position in type [-A,+B]java.lang.Object with java.util.Comparator[A] of trait Extractor 
     trait Extractor[-A,+B] extends Comparator[A] 
      ^


scala> trait Extractor[-A, +B] {     
    | def comp:Comparator[B] 
    | } 
<console>:7: error: covariant type B occurs in invariant position in type => java.util.Comparator[B] of method comp 
     def comp:Comparator[B] 
      ^

你看不到任何出路的這個或者是這裏的「使用Java泛型在斯卡拉傷害」的情況下這只是一個?

回答

12

隨着類型界限的幫助下有可能做到以下幾點:

scala> trait Extractor[-A, +B] { 
    | def comp:Comparator[_ <: B] 
    | } 
defined trait Extractor 
+0

謝謝。這樣可行。代碼還沒有運行,但你的代碼和比較器的有效聲明編譯保存和聲音。非常感謝。 – Agl 2010-09-15 12:53:57

+0

我知道這是一個完全不同的問題,但有沒有一個很好的論文/教程/博客,涵蓋類型界限和變體?我已經閱讀過這篇文章,但有人可能會爭辯說我沒有從他們身上學到太多東西)(另一方面,也許這就是我,所有人都再次閱讀它們) – Agl 2010-09-15 13:01:18

+2

這個很不錯(雖然它不是很好到目前爲止 - 沒有關於一些2.8功能的信息):http://programming-scala.labs.oreilly.com/ch12.html – 2010-09-15 13:06:07

7

您可以Extractor[A,B]使用@uncheckedVariance註釋延長Comparator[A]

scala> import scala.annotation.unchecked.uncheckedVariance 
import scala.annotation.unchecked.uncheckedVariance 

scala> trait Extractor[-A,+B] extends java.util.Comparator[A @uncheckedVariance] 
defined trait Extractor 

@uncheckedVariance這裏是安全的,因爲Comparator可能已被定義爲Comparator[-T]。有一個discussion圍繞使Scala 2.8使用這個註釋使Ordering協變。

編輯有關更多關於@uncheckedVariance的信息,請參閱this question

+0

恩,這也是一個不錯的。其實這可能是最終在我的代碼中的版本。 。 。只要我找到時間閱讀你發佈的帖子。非常感謝! – Agl 2010-09-15 20:17:57