繁体   English   中英

斯卡拉的逆变性

[英]Contravariance in scala

我是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。 由于参数化类型是逆变的,因此以下语句完全合法:

setGarbageCanForPlastic(new GarbageCan[Item])

现在,doSomething函数接受一个逆变量的Type参数。 如果我不知道类型是Base类“Item”还是子类“PlasticItem”,我该如何使用这种类型? 我可以做一些在子类中而不是在基类中允许的事情。 如果这是一个协变参数,这将没有问题,子类继承基类中的所有内容。

我输了吧?...希望有人可以帮助我。

首先, doSomething方法实际上除了基本上丢弃a之外什么也做不a因为它不知道A是什么。 为了使它更有用,你需要一个像class GarbageCan[-A <: Item]这样的绑定。

现在,假设setGarbageCanForPlastic(gc)调用gc.doSomething(new PlasticItem) 由于AGarbageCan[A]是逆变的,我们有GarbageCan[Item] <: GarbageCan[PlasticItem] <: GarbageCan[PlasticBottle] 实际上,函数调用setGarbageCanForPlastic(new GarbageCan[Item]))是安全的,因为GarbageCan[Item]doSomething可以处理任何包含PlasticItem Item ,而调用setGarbageCanForPlastic(new GarbageCan[PlasticBottle]))是不安全的,因为GarbageCan[PlasticBottle]doSomething可能不能够采取PlasticItem这不一定是PlasticBottle

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM