@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 出现在参数中,从未出现在返回类型中。

这就提出了一个问题:为什么它也不从Java接口延伸的Scala Collections库中使用?

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

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

有帮助吗?

解决方案

问题在于,使用了两次通用versababletemplate:一次用于可变的集合(其类型参数应该是不变的),并且一次用于不可变的集合(其中协方差始终是不变性的国王)。

generictraversabletemplate的Typechecks假设A类型参数的协方差或不变性。但是,当我们以可变特征继承它时,我们必须选择不变性。相反,我们希望在不可变的子类中协方差。

由于我们无法在generictraversabletemplate中的差异注释(;-))中抽象,因此我们可以根据子类实例化将其实例化,因此我们必须求助于铸造(@uncheckeckvariance本质上是一种基本上是一种式铸造) 。要进一步阅读,我建议我的论文(对不起;-)或我们最近的 比特罗特纸

其他提示

在我的论文中,我描述了一个微积分Scalina,它具有界限和差异注释作为类型语言的一部分(也可以作为一个早期版本作为一个 车间纸)。与此讨论的相关性是我要开发这种演算时要采取的下一步:在此基础上构建另一层,以便您可以在界限(简单)和差异注释(使我的头旋转)上抽象。实际上,您不仅会在那里添加1个额外的一层,还可以将您的多态性结构概括为各个级别,并使您的“属性”(界限,差异注释,需要隐性参数,...)为常规类型。具有特殊种类,所有这些都可以抽象。

在唯一性类型的背景下,Edsko de Vries很好地解释了“属性是类型”的想法。

独特性键入简化, ,Edsko de Vries,Rinus Plasmeijer和David Abrahamson。在Olaf Chitil,ZoltánHorváth和ViktóriaZsók(编辑):IFL 2007,LNCS 5083,第201-218页,2008年。

摘要:我们提出了一个唯一类型的系统,它比清洁的独特系统和我们先前提出的系统更简单。新型类型系统可以简单地实现并添加到现有编译器中,并且可以轻松扩展使用高级类型和不可思议的高级功能。我们在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();
          ()
        }
      }
    }
  }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top