是!这个问题的另一个,是的,我已经在stackoverflow上读了很多这个问题,但仍然不理解这个概念及其应用。
所以,我是Scala的新手,和许多人一样,我仍然没有理解方差的概念,我正在阅读《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的Supertype。
我不明白的是,什么意思是一个类型,在这种情况下,Function1[-C,+C],在第一个参数中是反变的?
书中说,当where X[String] is a supertype of X[Any], for some type X.
协变/逆变仅适用于参数化类型的子类,我的意思是,由于我们使用的是Function1,所以方差仅适用于Function1的子类型,是吗?
它实际上是如何工作的,我什么时候应该使用/需要它?
如果T'是T的子类,Container[T']是否被认为是Container[T]的子类?
[+T]
协变:C[T']是C[T]的一个子类,[-T]
反变型:C[T]是C[T']的一个子类
Function1
被定义为trait Function1[-T1, +R]
,因此参数是逆变的,结果类型是协变的。
这意味着,哪些参数是给定函数的参数类型的超类型,哪些结果类型是给定函数结果类型的子类型 在您的示例中,当您将不同的函数声明分配给类型为 也就是说,只有这些函数声明是 其他的都是C => C
的f
时,将只编译有效子类型的赋值。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
或不相关的类型。