对不起,我已经问了一些像这样的问题,但我仍然无法得到一个明确的答案,也许我的英语不好,表达方式不清楚使那些善良的人感到困惑。
当我阅读"类型参数化"在本文中:http://www.artima.com/pins1ed/type-parameterization.html,我看到有关类型位置的一些解释:
作为一个有点人为的例子,考虑以下类定义,其中几个位置的方差用^ +(对于正数)或^ - (对于负数)进行注释:
abstract class Cat[-T, +U] { def meow[W^-](volume: T^-, listener: Cat[U^+, T^-]^-) : Cat[Cat[U^+, T^-]^-, U^+]^+ }
除W
位置外,我能理解这堂课的大部分内容。我不明白为什么它标记为否定,整篇文档中没有解释。
它还说:
用+注释的类型参数只能在正位置使用,而用 - 注释的类型参数只能在负位置使用。
如何在位置-
中找到W
注释的类型以适应此负面位置?
答案 0 :(得分:4)
语言参考说:
确定类型参数具有方差位置意味着什么?
class Moo[+A, -B] {
def foo[X] (bar : Y) ...
所以Y处于逆向位置,这很明显。我们可以把B放在它的位置,但不是A。
但是X在逆变位置意味着什么?我们不能替代A或B或其他任何东西,它只是一个正式的参数!
这是真的,但是这个东西可以有从属位置,它们是类型,并且有变化。所以我们需要在跟踪我们翻转方差的次数时计算X的位置。这里没有X的从属条款,但请考虑一下:
class Moo[+A, -B] {
def foo[X >: Z] (bar : B) ...
我们可能用A或B代替Z,但哪个是正确的?那么,Z的位置与X的位置相反,并且X的位置与顶层的位置相反,这是协变的,因此Z也必须是协变的。我们来看看:
abstract class Moo[+A, -B] {
def foo[X >: A] (bar : B)
}
defined class Moo
看起来我们是对的!
答案 1 :(得分:1)
规范中有一个熟悉的例子:
Sequence.append
是pdf中的示例4.5.2,但目前没有编号。
abstract class Sequence[+A] {
def append[B >: A](x: Sequence[B]): Sequence[B]
}
在现实生活中,请参阅the doc for Seq.++
,忽略“用例”并点击“完整签名”以显示下限。
这与其他扩展操作(例如Option.getOrElse
)的模式相同,您可以获得比您开始时更广泛的类型。
这是一个在替代方面有意义的例子:
鉴于Seq[Fruit]
,我可以追加Seq[Orange]
。自Apple <: Fruit
起,我还可以将橘子追加到Seq[Apple]
并获得水果。
这就是B
类型参数想要被协变参数绑定的原因。出于方差检查的目的,B
的方差位置被归类为负值,但B
本身未注释。
有趣的是,这解析了:
scala> trait X { def append[-](): Unit }
defined trait X