2010-03-16 59 views
32

@uncheckedVariance可用于弥合Scala的声明网站方差注释和Java不变泛型之间的差距。什么时候在Scala中需要@uncheckedVariance,为什么它在GenericTraversableTemplate中使用?

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集合库中?

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

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

+0

大问题! – 2010-03-16 21:54:23

回答

25

问题是GenericTraversableTemplate使用两次:一次是可变集合(其类型参数应该是不变的),一次是不可变集合(协变总是为王)。

GenericTraversableTemplate的类型检测假设A类型参数为协方差或不变量。然而,当我们以可变特质继承它时,我们必须选择不变性。相反,我们想在不可变子类中使用协方差。

因为我们不能抽象GenericTraversableTemplate中的方差注释(还;-)),所以我们可以根据子类将它实例化为任一个,我们必须求助于转换(@uncheckVariance本质上是一个那种铸)。如要进一步了解,我建议我的论文(对不起;-)),或者我们最近bitrot paper

+0

谢谢!上周我很喜欢阅读纸质书,但它并没有专门处理将共同和不同版本的收藏整合到一个共同父母的问题。我想我会看看你的论文中有什么:) – retronym 2010-03-16 16:19:15

+0

那么,这主要是一个无耻的插件 - 我的论文并不直接处理这个确切的问题。尽管如此,它应该对这种更强大的多态性有更多的思考。我会在下面添加更多的想法。 – 2010-03-17 09:42:14

+0

“总是国王”......哈哈 – 2014-11-28 23:43:15

8

在我的论文我描述了一个微积分,Scalina,是有一定的限度&方差注解作为一种语言的一部分(早期版本也可作为workshop paper获得)。这个讨论的相关性是我想要开发这个微积分的下一个步骤:在其上创建另一个层,这样你就可以抽象超越范围(容易)和差异注释(让我的头脑旋转)。实际上,你不会只在这里增加一个额外的图层,而是泛化你的多态构造,使它们在各个层次上工作,并将你的“属性”(边界,变异注释,需要的隐式参数......)变成常规类型有特殊的种类,都是抽象的。

Edsko de Vries在唯一性类型的上下文中很好地解释了“属性是类型”的思想。

Uniqueness Typing Simplified, Edsko德弗里斯,里纳斯Plasmeijer,大卫亚伯拉罕。 在奥拉夫Chitil,佐尔坦霍瓦特和维多利亚Zsók(编辑):2007年 IFL,LNCS 5083,页201-218,2008年

摘要:本文提出了一种独特 类型系统比两个 清洁的更简单唯一性系统和我们之前提出的系统 。新的 类型系统很容易实现 实现并添加到现有的 编译器,并可以很容易地扩展 与先进的功能,如较高的 排名类型和impredicativity。我们 描述了我们在Morrow中的实现, 具有这两个特征的实验功能语言 。最后,我们 证明核心类型 系统相对于 按需调用lambda微积分的可靠性。

5

我发现在使用@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(); 
     () 
     } 
     } 
    } 
    } 
相关问题