scala - scala编译器如何定位方差标注的位置

标签 scala

我想了解编译器如何检查类型参数的位置是协变还是逆变。

据我所知,如果类型参数用 + 注释,这是协变注释,那么任何方法都不能使用该类/特征的类型参数键入输入参数。

例如,bar 不能有类型为 T 的参数。

class Foo[+T] {
  def bar(param: T): Unit = 
    println("Hello foo bar")
}

因为 bar() 的参数位置被认为是负数,这意味着该位置的任何类型参数都处于逆变位置。

我很好奇 Scala 编译器如何确定类/特征中的每个位置是正的、负的还是中性的。好像有一些规则,比如在某些情况下翻转它的位置,但没能理解清楚。

另外,如果可能的话,我想知道这些规则是如何定义的。例如,似乎在具有协变注释的类中定义的方法的参数,如 Foo 类中的 bar() 方法,应该具有逆变类类型。为什么?

最佳答案

I am curious how the Scala compiler can find if every location in the class/trait is positive, negative, or neutral. It seems that there exist some rules like flipping its position in some condition but couldn't understand it clearly.

Scala compiler有一个称为解析器的阶段(像大多数编译器一样),它遍历文本并解析出标记。这些标记之一称为方差。如果我们深入细节,有一个方法叫做 Parsers.typeParamClauseOpt它负责解析出类型参数子句。与您的问题相关的部分是:

def typeParam(ms: Modifiers): TypeDef = {
  var mods = ms | Flags.PARAM
  val start = in.offset
  if (owner.isTypeName && isIdent) {
    if (in.name == raw.PLUS) {
      in.nextToken()
      mods |= Flags.COVARIANT
    } else if (in.name == raw.MINUS) {
      in.nextToken()
      mods |= Flags.CONTRAVARIANT
    }
  }

解析器在类型参数签名中查找+- 符号,并创建一个名为TypeDef 的类来描述类型和声明它是协变的、逆变的或不变的。

Also, if possible, I would like to know how these rules are defined.

方差规则是通用的,它们源于一个叫做 Category Theory 的数学分支.更具体地说,它们来自 Covariant and Contravariant Functors以及两者之间的组成。如果您想了解更多有关这些规则的信息,那将是我要走的路。

另外,还有一个类叫做Variance在 Scala 编译器中,如果您想更深入地了解,它看起来像是一个关于方差规则的辅助类。

关于scala - scala编译器如何定位方差标注的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49334070/

相关文章:

python - col 函数如何知道我们引用的是哪个 DataFrame?

scala - 如何使用 Spark-Scala 本地程序从谷歌云存储中读取简单的文本文件

scala - 为什么在scala中的代码块之前给出类名?

scala - 使用 Spark/Scala 根据列值减少组中的行

scala - 使用 Spark Scala 将数据帧转换为 HashMap

scala - 将数据框中的向量列转换回数组列

scala - Spark collect()/count() 永远不会完成,而 show() 运行速度很快

scala - 可以使用 scalaz Arrow 组合吗?

scala - Fs2 Stream.Compiler 未找到(找不到隐含值 Compiler[[x]F[x],G])

scala - 无法连接到 Scala 测试中的 Cassandra docker 容器