文档章节

为什么需要协变 逆变

jinlei_du
 jinlei_du
发布于 2017/02/24 17:14
字数 421
阅读 0
收藏 0

#为什么需要协变 逆变

凡事物的产生必有其因,一个概念的产生也非平白无故,协变 逆变是在泛型的基础上孕育出来。类型系统中,泛型提供了基于concept进行编程能力,可以用于创建一个标准容器库基于相同模板来处理不同类型。 进一步,为了分配和使用泛型类型方面提供更大的灵活性,协变 逆变的概念也被抽离出来。

#何为协变 逆变

  • 协变 能够使用比原始指定的类型派生程度更大的类型。

  • 逆变 能够使用比原始指定的类型更泛型(派生程度更小)的类型。

在Scala 标准库中 trait Function1[-T1, +R] extends AnyRef { self => def apply(v1: T1): R override def toString() = "<function1>" } R声明为协变,我们先固定住T(声明逆变)排除干扰。 val covariant_f1:Int => String = x => ... val covariant_f2:Int => Any = x => ...

covariant_f1 返回值类型为String,covariant_f2为Any而且String是Any的子类型, covariant_f2可用的地方,covariant_f1都可用,反之无效,根据里氏替换原则子类可以任意替换父类, 那么Function[Int,String]应该算作Function[Int,Any]子类型。

同理对于声明为逆变类型的R

val contravariance_f1:Int => String = x => ... val contravariance_f2:Any => String = x => ...

凡是contravariance_f1可以使用的地方,contravariance_f2都是可以用的,既Function[Int,String] 是Function[Any,String]是Function[Any,String]的子类。

从中我们可以看出协变和逆变的引入事为了高阶类型F[A], F[B]之间, 也能像低阶类型A, B那样能够有型变的能力

© 著作权归作者所有

共有 人打赏支持
上一篇: 何为Akka Actor
下一篇: 何为Akka Actor
jinlei_du
粉丝 0
博文 2
码字总数 1031
作品 0
闵行
程序员
私信 提问
Java中逆变与协变

看下面一段代码 Number num = new Integer(1); ArrayList<Number> list = new ArrayList<Integer>(); //type mismatch List<? extends Number> list = new ArrayList<Number>();list.add(new......

Hosee
2016/02/25
159
0
协变和逆变(转载)

前言 个人感觉协变(Covariance)与逆变(Contravariance)是 C# 4 中最难理解的一个特性了,因为 C# 4 用了一个非常直观的语法(和关键字),在很多情况下,这似乎很简单,用于输入的参数,用于...

jeffcky
2015/08/15
0
0
C# 4.0新特性-"协变"与"逆变"以及背后的编程思想

在《上篇》中我们揭示了“缺省参数”的本质,现在我们接着来谈谈C#4.0中另一个重要的新特性:协变(Covariance)与逆变(Contravariance)。对于协变与逆变,大家肯定不会感到陌生,但是我相...

长平狐
2012/09/04
38
0
Scala的协变covariant(+),逆变contravariant(-),上界(:)

原文:https://my.oschina.net/xinxingegeya/blog/486671 Scala的协变(+),逆变(-),上界(<:),下界(>:) 协变covariant、逆变contravariant、不可变invariant 对于一个带类型参数的类型,比如...

u013063153
2017/11/09
0
0
Scala的协变(+),逆变(-),上界(:)

Scala的协变(+),逆变(-),上界(<:),下界(>:) 协变covariant、逆变contravariant、不可变invariant 对于一个带类型参数的类型,比如 List[T],如果对A及其子类型B,满足 List[B]也符合List[...

秋风醉了
2015/08/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

剖析Elasticsearch的IndexSorting:一种查询性能优化利器

摘要: 前言 前两周写过一篇《基于Lucene查询原理分析Elasticsearch的性能》,在最后留了一个彩蛋,说下一篇会介绍一种可以极大的优化查询性能的技术。本文就来介绍这种技术——IndexSortin...

阿里云官方博客
34分钟前
1
0
Go 使用channel控制并发

前言 channel一般用于协程之间的通信,channel也可以用于并发控制。比如主协程启动N个子协程,主协程等待所有子协程退出后再继续后续流程,这种场景下channel也可轻易实现。 场景示例 总结 ...

恋恋美食
59分钟前
3
0
斐波那契堆的理解,节点mark属性和势函数

斐波那契堆 看了好多博客,都是照搬算法导论的内容,没有自己的理解,比如为什么有mark属性,势函数的作用,以及为什么叫斐波那契堆,下面说说鄙人的理解。 势函数 势函数是根节点个数加上2...

杨喆
今天
7
0
NIO源码详解

阻塞io和无阻塞io: 阻塞io是指jdk1.4之前版本面向流的io,服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒 ...

沉稳2018
今天
2
0
如何把已经提交的commit, 从一个分支放到另一个分支

在本地master提交了一个commit(8d85d4bca680a5dbcc3e5cfb3096d18cd510cc9f),如何提交的test_2分之上? git checkout test_2git cherry-pick 8d85d4bca680a5dbcc3e5cfb3096d18cd510cc9f......

stephen_wu
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部