【问题标题】:Confused with Variance对方差感到困惑
【发布时间】:2011-04-11 00:38:08
【问题描述】:

鉴于以下情况:

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)

我是否遗漏了一些基本的方差原则?

【问题讨论】:

    标签: scala variance


    【解决方案1】:

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

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

    这完全没问题。就像你手动做的一样

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

    这只是编译器应用的巨大魔法的一小部分,它试图弄清楚你对类型的含义,而不是让你全部输入。

    【讨论】:

    • 谢谢。当编译器假设开发人员希望它工作时,编译器似乎正在缩短方法 p 的 Crate 不变性。我假设必须将 Crate 定义为 Crate[+T] 才能使 p 方法与 cro, cra 一起使用。
    • @ssanj - 你说得对,它必须定义为+T 才能与crocra 一起使用,它们已经分配了它们的类型。但是当你不指定类型并生成新的东西时,它假定你想要一些合理的东西,如果有一个合理的东西。
    猜你喜欢
    • 1970-01-01
    • 2013-07-27
    • 2017-03-20
    • 2013-07-19
    • 2019-09-13
    • 2012-07-22
    • 2013-05-13
    • 2020-04-16
    • 2023-03-08
    相关资源
    最近更新 更多