与方差混淆

发布于 2024-10-31 11:57:41 字数 1152 浏览 5 评论 0原文

鉴于以下情况:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

疑心病 2024-11-07 11:57:41

在后一种情况下,编译器假设您希望它工作,并且实际上说

p(Crate( (new Apple): Fruit ))

这是完全可以的。这与您手动执行的操作相同。

val f: Fruit = new Apple   // totally fine
p(Crate(f))                // Also totally fine

这只是编译器应用的巨大魔法的一小部分,它试图弄清楚您对类型的含义,而不需要您将其全部键入。

In the latter cases, the compiler assumes that you want this to work and actually says

p(Crate( (new Apple): Fruit ))

which is perfectly okay. It's the same as if you manually did

val f: Fruit = new Apple   // totally fine
p(Crate(f))                // Also totally fine

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文