当@uncheckedVariance需要Scala和为什么它在GenericTraversableTemplate使用吗? [英] When is @uncheckedVariance needed in Scala, and why is it used in GenericTraversableTemplate?

查看:126
本文介绍了当@uncheckedVariance需要Scala和为什么它在GenericTraversableTemplate使用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

@uncheckedVariance 可用于弥补Scala的声明,网站方差注释和Java的泛型不变之间的差距。

@uncheckedVariance can be used to bridge the gap between Scala's declaration site variance annotations and Java's invariant generics.

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 出现在参数和从来没有在返回类型的类型参数。

This says that java.util.Comparator is naturally contra-variant, that is the type parameter T appears in parameters and never in a return type.

这引出了一个问题:为什么它也以不从Java接口扩展了Scala集合库使用

This begs the question: why is it also used in the Scala collections library which doesn't extends from Java interfaces?

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

什么是有效的用途这个注释?

What are the valid uses for this annotation?

推荐答案

问题在于GenericTraversableTemplate使用了两次:一次是针对可变集合(其中,其类型参数应该是不变的),并且一旦为不可改变的集合(其中,协方差是不可避免王)。

The problem is that GenericTraversableTemplate is used twice: once for mutable collections (where its type parameter should be invariant), and once for immutable collections (where covariance is invariably king).

GenericTraversableTemplate的typechecks假设无论是协方差或不变性为A类型参数。然而,当我们在一个可变的特点继承它,我们必须选择不变性。相反,我们希望协方差一个不变的子类。

GenericTraversableTemplate's typechecks assuming either covariance or invariance for the A type parameter. However, when we inherit it in a mutable trait, we have to pick invariance. Conversely, we'd like covariance in an immutable subclass.

由于我们可以通过在GenericTraversableTemplate方差注释(尚未;-))不是抽象的,这样我们就可以在实例它任何一个依赖于子类,我们不得不诉诸铸造(@uncheckVariance本质上是一种-投)。为进一步阅读,我建议我的论文(对不起;-))或我们最近的<一个href=\"http://scholar.google.com/scholar?q=%22Fighting+bit+Rot+with+Types+%28Experience+Report+Scala+Collections%29.%22\">bitrot纸

Since we can't abstract over the variance annotation (yet ;-)) in GenericTraversableTemplate, so that we could have instantiated it to either one depending on the subclass, we have to resort to casting (@uncheckVariance is essentially a kind-cast). For further reading, I recommend my dissertation (sorry ;-)) or our recent bitrot paper

这篇关于当@uncheckedVariance需要Scala和为什么它在GenericTraversableTemplate使用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆