是!另一个问题,是的,我已经在堆栈溢出中读到了很多这个问题,但仍然不理解这个概念和它的应用。
所以,我是Scala的新成员,就像许多人一样,我仍然没有理解反方差的概念,我正在阅读Programming Scala,第2版,在第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.
协/逆方差仅适用于参数化类型的子类,我的意思是,由于我们使用的是Function1,所以方差只适用于Function1的子类型,是吗?
它实际上是如何工作的,我什么时候应该使用/需要它?
发布于 2016-04-06 19:50:19
如果T‘是T的一个子类,那么ContainerT’被认为是ContainerT的子类吗?
[+T]协变:CT‘是CT的一个子类, contravariant: CT是CT的一个子类
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或不相关的类型。
https://stackoverflow.com/questions/36459965
复制相似问题