【发布时间】:2016-07-05 15:28:51
【问题描述】:
我是 scala 的新手。我试图弄清楚整个逆变关系是如何工作的。我了解协变和不变的概念,并且我也知道如何在实践中实现它们。 我也了解逆变(协方差的逆)的概念以及它是如何在 Scala 的 Function1 特征中实现的。它为您提供了一个抽象,而无需为不同的类重新定义 Function1 实现。但是,我还是没完全明白,奇怪?现在,我快到了……我怎样才能用逆变来解决以下问题:
class GarbageCan[-A] {
def doSomething(a: A): Unit ={
// do something with 'a' of subtype that is not possible with the supertype
}
}
def setGarbageCanForPlastic(gc: GarbageCan[PlasticItem]): Unit = {
}
以上示例摘自http://blog.kamkor.me/Covariance-And-Contravariance-In-Scala/。关于这个主题的一个非常好的解释。层次结构如下:Item(基类)-> PlasticItem(子类)-> PlasticBottle(子类的子类)
setGarbageCanForPlastic 函数接受类型为 PlasticItem 的 GarbageCan。因为Parameterized类型是逆变的,所以下面的语句是完全合法的:
setGarbageCanForPlastic(new GarbageCan[Item])
现在,doSomething 函数接受一个逆变的 Type 参数。如果我不知道该类型是基类“Item”还是子类“PlasticItem”,我该如何使用这种类型?我可以做一些在子类中而不是在基类中允许的事情。如果这是一个协变参数,那就没问题了,子类继承了基类的所有内容。
我弄丢了吧?...希望有人能帮帮我。
【问题讨论】:
-
为什么只担心
GarbageCan[Item]?例如,有什么可以阻止某人创建GrabageCan[Option[List[Int]]]?暂时忽略逆变方差。即使只是GrabageCan[A],您如何想象您的doSomething会起作用? -
好问题...它应该只用作正文中的“类型”?
-
好吧,我不确定你所说的“它”是什么意思,以及你在说谁的“身体”,所以我不知道 :) 底线是,你首先 提出一个实际用例,然后然后 看看逆变/协方差/不变性是否适合它,而不是相反。
标签: scala inheritance functional-programming