我想了解编译器如何检查类型参数的位置是协变还是逆变。
据我所知,如果类型参数用 + 注释,这是协变注释,那么任何方法都不能使用该类/特征的类型参数键入输入参数。
例如,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/