与方差混淆
鉴于以下情况:
trait Fruit
class Apple extends Fruit
class Orange extends Fruit
case class Crate[T](value:T)
def p(c:Crate[Fruit]) { }
val cra = Crate(new Apple)
val cro = Crate(new Orange)
由于 Crate 是不变的,所以我无法执行以下操作(如预期):
scala> val fruit:Crate[Fruit] = cra
<console>:10: error: type mismatch;
found : Crate[Apple]
required: Crate[Fruit]
val fruit:Crate[Fruit] = cra
^
scala> val fruit:Crate[Fruit] = cro
<console>:10: error: type mismatch;
found : Crate[Orange]
required: Crate[Fruit]
val fruit:Crate[Fruit] = cro
scala> p(cra)
<console>:12: error: type mismatch;
found : Crate[Apple]
required: Crate[Fruit]
p(cra)
^
scala> p(cro)
<console>:12: error: type mismatch;
found : Crate[Orange]
required: Crate[Fruit]
p(cro)
但是为什么当 Crate 不是协变时我可以使用这些调用方法 p ? :
scala> p(Crate(new Apple))
Crate(line2$object$$iw$$iw$Apple@35427e6e)
scala> p(Crate(new Orange))
Crate(line3$object$$iw$$iw$Orange@33dfeb30)
我是否错过了一些方差的基本原则?
Given the following:
trait Fruit
class Apple extends Fruit
class Orange extends Fruit
case class Crate[T](value:T)
def p(c:Crate[Fruit]) { }
val cra = Crate(new Apple)
val cro = Crate(new Orange)
since Crate is invariant, I can't do the following (as expected):
scala> val fruit:Crate[Fruit] = cra
<console>:10: error: type mismatch;
found : Crate[Apple]
required: Crate[Fruit]
val fruit:Crate[Fruit] = cra
^
scala> val fruit:Crate[Fruit] = cro
<console>:10: error: type mismatch;
found : Crate[Orange]
required: Crate[Fruit]
val fruit:Crate[Fruit] = cro
scala> p(cra)
<console>:12: error: type mismatch;
found : Crate[Apple]
required: Crate[Fruit]
p(cra)
^
scala> p(cro)
<console>:12: error: type mismatch;
found : Crate[Orange]
required: Crate[Fruit]
p(cro)
But why can I call method p with these when Crate is not covariant? :
scala> p(Crate(new Apple))
Crate(line2$object$iw$iw$Apple@35427e6e)
scala> p(Crate(new Orange))
Crate(line3$object$iw$iw$Orange@33dfeb30)
Have I missed some basic principles of variance?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在后一种情况下,编译器假设您希望它工作,并且实际上说
这是完全可以的。这与您手动执行的操作相同。
这只是编译器应用的巨大魔法的一小部分,它试图弄清楚您对类型的含义,而不需要您将其全部键入。
In the latter cases, the compiler assumes that you want this to work and actually says
which is perfectly okay. It's the same as if you manually did
This is just a small part of the immense wizardry that the compiler applies to try to figure out what you mean with your types without making you type it all out.