@uncheckedVariance
可以用来弥合Scala的声明站点方差注释和Java的不变泛型之间的差距.
scala> import java.util.Comparator
import java.util.Comparator
scala> trait Foo[T] extends Comparator[T]
defined trait Foo
scala> trait Foo[-T] extends Comparator[T]
<console>:5: error: contravariant type T occurs in invariant position in type [-T]java.lang.Object with java.util.Comparator[T] of trait Foo
trait Foo[-T] extends Comparator[T]
^
scala> import annotation.unchecked._
import annotation.unchecked._
scala> trait Foo[-T] extends Comparator[T @uncheckedVariance]
defined trait Foo
Run Code Online (Sandbox Code Playgroud)
这表示java.util.Comparator自然是反变体,即类型参数T
出现在参数中,而不是返回类型.
这就引出了一个问题:为什么它还在Scala集合库中使用,它不是从Java接口扩展的?
trait GenericTraversableTemplate[+A, +CC[X] <: Traversable[X]] extends HasNewBuilder[A, CC[A] @uncheckedVariance]
Run Code Online (Sandbox Code Playgroud)
此注释的有效用途是什么?
请看一下下面的代码,其中Extractor[A,B]
是通用框架的一部分,其他一切应该被视为"客户端代码"(我把它煮了很多,并重命名为所有内容.所以不要介意Extractor
似乎没有太有用了).
scala> abstract class Extractor[A,B] {
| def extract(d:A):B
| def stringRepr(d:A):String
| }
defined class Extractor
scala> sealed abstract class Value
defined class Value
scala> case class IntValue(i:Int) extends Value
defined class IntValue
scala> case class StringValue(s:String) extends Value
defined class StringValue
scala> case class Data(i:Int, s:String)
defined class Data
scala> sealed abstract class MyExtractor[Value] extends Extractor[Data, Value] {
| def stringRepr(d:Data) = extract(d) match {
| case IntValue(i) => i.toString
| case StringValue(s) => …
Run Code Online (Sandbox Code Playgroud)