scala - Scala 中什么时候需要 @uncheckedVariance?为什么在 GenericTraversableTemplate 中使用它?

标签 scala scala-2.8 annotations unchecked variance

@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

这表明 java.util.Comparator 本质上是逆变的,即类型参数 T 出现在参数中,而从不出现在返回类型中。

这就提出了一个问题:为什么它也用在 Scala 集合库中,而它不是从 Java 接口(interface)扩展的?

trait GenericTraversableTemplate[+A, +CC[X] <: Traversable[X]] extends HasNewBuilder[A, CC[A] @uncheckedVariance]

此注释的有效用途是什么?

最佳答案

问题在于 GenericTraversableTemplate 使用了两次:一次用于可变集合(其类型参数应保持不变),一次用于不可变集合(其中协方差始终为王)。

GenericTraversableTemplate 的类型检查假设 A 类型参数具有协变性或不变性。然而,当我们以可变特征继承它时,我们必须选择不变性。相反,我们希望在不可变的子类中实现协变。

由于我们还不能抽象 GenericTraversableTemplate 中的方差注释(还;-)),以便我们可以根据子类将其实例化为任一注释,因此我们必须诉诸强制转换(@uncheckVariance 本质上是一种- throw )。为了进一步阅读,我推荐我的论文(抱歉;-))或我们最近的bitrot paper

关于scala - Scala 中什么时候需要 @uncheckedVariance?为什么在 GenericTraversableTemplate 中使用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2454281/

相关文章:

java - 如何让 Jackson mixin 与私有(private)字段一起工作?

generics - 在 Scala 参数化(泛型)类型错误中使用 Guava 的简单缓存管理器

scala - 在 Scala 中将列表转换为集合

scala - 函数处理 Array[T] 或 List[T] 或 Iterable[T] 的函数

scala - 我们可以将 Any 与泛型类型匹配吗? [斯卡拉 2.8]

java - 自定义注释处理器 - 带注释的检测方法

java - 自动包装@Repeatable 注解的顺序

sql - 我们是否有数据库访问层可以轻松切换到 Scala 中的其他数据库

scala - 如何在 ScalaQuery 中获取类对象作为结果而不是元组?

scala - 在其他长期运行的 Actor 在场的情况下,如何防止 Actor 饥饿?