ret*_*nym 38 annotations scala unchecked variance scala-2.8
@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)
此注释的有效用途是什么?
Adr*_*ors 28
问题是GenericTraversableTemplate被使用了两次:一次用于可变集合(其类型参数应该是不变的),一次用于不可变集合(其中协方差总是为王).
GenericTraversableTemplate的类型检查假定A类型参数的协方差或不变性.但是,当我们以可变特性继承它时,我们必须选择不变性.相反,我们喜欢不可变子类中的协方差.
由于我们无法在GenericTraversableTemplate中抽象出方差注释(但是;-)),因此我们可以根据子类将其实例化为任何一个,我们必须求助于转换(@uncheckVariance本质上是一种类型转换) .为了进一步阅读,我推荐我的论文(对不起;-))或我们最近的bitrot论文
在我的论文中,我描述了一个微积分Scalina,它具有边界和方差注释作为种类语言的一部分(早期版本也可作为研讨会论文提供).与此讨论的相关性是我想要开发此微积分的下一步:在此基础上构建另一层,以便您可以抽象超出边界(简单)和方差注释(使我的头部旋转).实际上,你不仅要在那里添加一个额外的层,而是概括你的多态构造,使它们在所有层次上工作,并将你的"属性"(边界,方差注释,必需的隐式参数......)变成常规类型特殊种类,都是抽象的.
Edsko de Vries在唯一性类型的背景下很好地解释了"属性是类型"的想法.
Uniqueing Typing Simplified,Edsko de Vries,Rinus Plasmeijer和David Abrahamson.在Olaf Chitil,ZoltánHorváth和ViktóriaZsók(Eds.):IFL 2007,LNCS 5083,pp.201-218,2008.
摘要:我们提出了一种唯一性类型系统,它比Clean的唯一性系统和我们之前提出的系统更简单.新类型系统可以直接实现并添加到现有编译器中,并且可以通过更高级别类型和不可靠性等高级功能轻松扩展.我们在Morrow中描述了我们的实现,这是一种具有这些功能的实验性功能语言.最后,我们证明了核心类型系统相对于需要调用的lambda演算的可靠性.
我发现了另一个使用@uncheckedVariance的时间 - 返回抽象类型参数的默认值的合成方法:
M:\>scala -Xprint:typer -e "class C { def p[T >: Null](t: T = null) = t }"
[[syntax trees at end of typer]]// Scala source: (virtual file)
package <empty> {
final object Main extends java.lang.Object with ScalaObject {
def this(): object Main = {
Main.super.this();
()
};
def main(argv: Array[String]): Unit = {
val args: Array[String] = argv;
{
final class $anon extends scala.AnyRef {
def this(): anonymous class $anon = {
$anon.super.this();
()
};
class C extends java.lang.Object with ScalaObject {
<synthetic> def p$default$1[T >: Null <: Any]: Null @scala.annotation.unchecked.uncheckedVariance = null;
def this(): this.C = {
C.super.this();
()
};
def p[T >: Null <: Any](t: T = null): T = t
}
};
{
new $anon();
()
}
}
}
}
Run Code Online (Sandbox Code Playgroud)