首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala协方差与反方差

Scala协方差与反方差
EN

Stack Overflow用户
提问于 2016-04-06 18:55:04
回答 1查看 170关注 0票数 0

是!另一个问题,是的,我已经在堆栈溢出中读到了很多这个问题,但仍然不理解这个概念和它的应用。

所以,我是Scala的新成员,就像许多人一样,我仍然没有理解反方差的概念,我正在阅读Programming Scala,第2版,在第283页中,我用下面的示例开始解释协方差和对比方差:

给出层次结构:

代码语言:javascript
复制
class CSuper { def msuper() = println("CSuper") }
class C extends CSuper { def m() = println("C") }
class CSub extends C { def msub() = println("CSub") }

然后是一个函数和一些使用示例:

代码语言:javascript
复制
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的子类型,是吗?

它实际上是如何工作的,我什么时候应该使用/需要它?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-06 19:50:19

如果T‘是T的一个子类,那么ContainerT’被认为是ContainerT的子类吗? [+T] 协变:CT‘是CT的一个子类, contravariant: CT是CT的一个子类

Function1被定义为trait Function1[-T1, +R],因此参数是反变的,结果类型是协变的。

这意味着,函数,哪些参数是给定函数的参数类型的超级类型,哪些结果类型是给定函数的结果类型的子类型,它本身就是给定函数的子类型。

在您的示例中,当您将不同的函数声明分配给类型为fC => C时,只有有效子类型的赋值才会编译。

也就是说,只有这些函数声明是C => C的有效子类型。

代码语言:javascript
复制
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或不相关的类型。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36459965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档