scala中的协变类型参数需要在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] :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] | } :7: error: covariant type B occurs in invariant position in type => java.util.Comparator[B] of method comp def comp:Comparator[B] ^
你有没有看到这种情况,或者这只是“在scala中使用javagenerics”的情况之一?
在类型边界的帮助下,可以执行以下操作:
scala> trait Extractor[-A, +B] { | def comp:Comparator[_ <: B] | } defined trait Extractor
您可以使用@uncheckedVariance
注释使Extractor[A,B]
扩展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]
。 有一个关于使用这个注释为Scala 2.8制作Ordering
covariant的讨论 。
编辑有关@uncheckedVariance
更多信息,请参阅此问题 。