Scala Co and Contravariance



是!这个问题的另一个,是的,我已经在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 => Cf时,将只编译有效子类型的赋值。

也就是说,只有这些函数声明是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或不相关的类型。

相关内容

  • 没有找到相关文章

最新更新