斯卡拉有限公司和逆变(Scala Co and Contravariance)

2019-11-04 04:36发布

是! 另外这个问题的,是的,我已经读了很多的这个问题在计算器,仍然不明白这个概念,它的应用。

所以,我我新的后起之秀Scala和很多人一样,我仍然没有得到逆变的概念,我读的编程斯卡拉,第二版,283页开始合作和逆变与解释下面的例子:

给人的层次结构:

class CSuper { def msuper() = println("CSuper") }
class C extends CSuper { def m() = println("C") }
class CSub extends C { def msub() = println("CSub") }

然后有一个功能和使用的一些例子:

var f: C => C = (c: C) => new C
    f         = (c: CSuper) => new CSub
    f         = (c: CSuper) => new C
    f         = (c: C) => new CSub
    f         = (c: CSub) => new CSuper // COMPILATION ERROR!

在java中想我知道,最后一个表达式不能编译,因为CSuper是CSUB的超类型。

我不明白是什么意思一个类型,在这种情况下,功能1 [-C,+ C],是第一个参数逆变?

该书说,对于逆变时where X[String] is a supertype of X[Any], for some type X.

共/逆变是在参数化类型的子类只是appliable,我的意思是,因为我们使用的是功能1,方差只适用于功能1亚型,是吗?

它是如何实际工作,当我应该使用/需要它吗?

Answer 1:

如果T“是T的子类,是容器[T”]考虑容器[T]的子类?

[+T] 协变 :C [T']为C [T]的子类,
[-T] 逆变:C [T]是的一个子类C [T']

Function1被定义为trait Function1[-T1, +R]所以参数是逆变和结果类型为协变。

这意味着,函数,自变量是参数类型给定功能的超类型 ,并且其结果类型为结果类型给定功能的亚型是本身给定功能的子类型。

在你的榜样,因为你是来分配不同的函数声明f型的C => C ,唯一有效的亚型的分配将编译。

即,只有这些函数声明都是有效亚型C => C

var f: C => C = (c: C) => new C
f         = (c: C) => new C
f         = (c: C) => new CSub
f         = (c: CSuper) => new C
f         = (c: CSuper) => new CSub

一切是任超类型C => C并且不能被分配给f或无关的类型。



文章来源: Scala Co and Contravariance