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

Agl*_*Agl 12 java generics scala scala-2.8

我有一个看起来像这样的特征(我可以在这个相关问题上找到一些更多的信息,虽然我不认为,这个问题需要它)

trait Extractor[-A,+B] {
  def extract(d:A):B
  //lots of other things
}
Run Code Online (Sandbox Code Playgroud)

要在现有的java框架中使用它,我希望Extractor它有一个函数返回一个Comparator[B](是java.util.Comparator)或更好的扩展Comparator[A].现在这会产生问题,因为Comparators类型参数应该是不变的,而且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]
             ^
Run Code Online (Sandbox Code Playgroud)

你有没有看到这种情况,或者这只是"在scala中使用java泛型"的情况之一?

Vas*_*iuk 12

在类型边界的帮助下,可以执行以下操作:

scala> trait Extractor[-A, +B] {
     | def comp:Comparator[_ <: B]
     | }
defined trait Extractor
Run Code Online (Sandbox Code Playgroud)

  • 这个非常好(虽然它不是最新的 - 没有关于某些2.8功能的信息):http://programming-scala.labs.oreilly.com/ch12.html (2认同)

Ben*_*ngs 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
Run Code Online (Sandbox Code Playgroud)

@uncheckedVariance在这里是安全的,因为Comparator可以被定义为Comparator[-T].有一个关于Ordering使用这个注释为Scala 2.8 制作协变的讨论.

编辑有关详细信息,请参阅此问题@uncheckedVariance.