scala中的协变类型参数需要在java接口中保持不变

时间:2010-09-15 09:18:35

标签: java generics scala scala-2.8

我有一个看起来像这样的特征(可以在this related question by myself找到更多的信息,虽然我不认为,这个问题需要它)

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]
             ^

你有没有看到任何出路或这只是“在scala中使用java泛型伤害”的情况之一?

2 个答案:

答案 0 :(得分:12)

借助类型界限,可以执行以下操作:

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

答案 1 :(得分:7)

您可以使用Extractor[A,B]注释Comparator[A]扩展@uncheckedVariance

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]。围绕使用此注释为Scala 2.8制作Ordering协变有discussion

修改有关@uncheckedVariance的详情,请参阅this question