[Scala] 了解 协变 与 逆变
首先定义一个类 A,其参数类型 T 为协变,类中包含一个方法 func,该方法有一个类型为 T 的参数:
class A[+T] {
def func(x: T) {}
}
此时在 x 处会有异常提示,covariant type T occurs in contravariant position in type T of value x
val father: A[AnyRef] = null.asInstanceOf[A[AnyRef]] // 父类对象,包含方法 func(x: AnyRef)
val child: A[String] = null.asInstanceOf[A[String]] // 子类对象,包含方法 func(x: String)
def otherFunc(x: A[AnyRef]): Unit = {
x.func(Nil)
}

val fatherFather: A[Any] = null.asInstanceOf[A[Any]] // func(x: Any)
otherFunc(fatherFather)// 如果 T 为协变,此处会提示异常
总结:
- 如果将 T 作为 func 方法的返回值类型,即处于协变点,就可以编译通过。
class B[+T] {
def func(): T = {
null.asInstanceOf[T]
}
}
// 与 Function0[+A] 等价
- 或者将类型参数 T 改为逆变,
class A[-T] {
def func(x: T) {}
}
// 与 Function1[-A, Unit] 等价
val father: A[AnyRef] = null.asInstanceOf[A[AnyRef]] // func(x: AnyRef)
val fatherFather: A[Any] = null.asInstanceOf[A[Any]] // func(x: Any)
def otherFunc(x: A[AnyRef]): Unit = {
x.func(Nil)
}
otherFunc(father) // success
otherFunc(fatherFather)// success
参考网址:
span::selection, .codemirror-line > span > span::selection { background: #d7d4f0; }.codemirror-line::-moz-selection, .codemirror-line > span::-moz-selection, .codemirror-line > span > span::-moz-selection { background: #d7d4f0; }.cm-searching {background: #ffa; background: rgba(255, 255, 0, .4);}.cm-force-border { padding-right: .1px; }@media print { .codemirror div.codemirror-cursors {visibility: hidden;}}.cm-tab-wrap-hack:after { content: ""; }span.codemirror-selectedtext { background: none; }.codemirror-activeline-background, .codemirror-selected {transition: visibility 0ms 100ms;}.codemirror-blur .codemirror-activeline-background, .codemirror-blur .codemirror-selected {visibility:hidden;}.codemirror-blur .codemirror-matchingbracket {color:inherit !important;outline:none !important;text-decoration:none !important;}
-->
li {list-style-type:decimal;}.wiz-editor-body ol.wiz-list-level2 > li {list-style-type:lower-latin;}.wiz-editor-body ol.wiz-list-level3 > li {list-style-type:lower-roman;}.wiz-editor-body blockquote {padding:0 12px;padding:0 0.75rem;}.wiz-editor-body blockquote > :first-child {margin-top:0;}.wiz-editor-body blockquote > :last-child {margin-bottom:0;}.wiz-editor-body img {border:0;max-width:100%;height:auto !important;margin:2px 0;}.wiz-editor-body table {border-collapse:collapse;border:1px solid #bbbbbb;}.wiz-editor-body td,.wiz-editor-body th {padding:4px 8px;border-collapse:collapse;border:1px solid #bbbbbb;min-height:28px;word-break:break-all;box-sizing: border-box;}.wiz-hide {display:none !important;}
-->
[Scala] 了解 协变 与 逆变的更多相关文章
- (转)Scala中协变(+)、逆变(-)、上界(<:)、下界(>:)简单介绍
看源码的时候看到: trait ExtensionId[T <: Extension] { 没见过这个符号啊<: Scala上界(<:)和下界(>:) 1) U >: T ...
- scala学习笔记-类型参数中协变(+)、逆变(-)、类型上界(<:)和类型下界(>:)的使用
转载自 fineqtbull http://fineqtbull.iteye.com/blog/477994 有位je上的同学来短信向我问起了Scala类型参数中协变.逆变.类型上界和类型下界的 ...
- Scala类型参数中协变(+)、逆变(-)、类型上界(<:)和类型下界(>:)的使用
转自:http://fineqtbull.iteye.com/blog/477994#bc2364938 有位je上的同学来短信向我问起了Scala类型参数中协变.逆变.类型上界和类型下界的使用方法和 ...
- Scala 基础(十六):泛型、类型约束-上界(Upper Bounds)/下界(lower bounds)、视图界定(View bounds)、上下文界定(Context bounds)、协变、逆变和不变
1 泛型 1)如果我们要求函数的参数可以接受任意类型.可以使用泛型,这个类型可以代表任意的数据类型. 2)例如 List,在创建 List 时,可以传入整型.字符串.浮点数等等任意类型.那是因为 Li ...
- Scala中的协变,逆变,上界,下界等
Scala中的协变,逆变,上界,下界等 目录 [−] Java中的协变和逆变 Scala的协变 Scala的逆变 下界lower bounds 上界upper bounds 综合协变,逆变,上界,下界 ...
- Scala教程之:深入理解协变和逆变
文章目录 函数的参数和返回值 可变类型的变异 在之前的文章中我们简单的介绍过scala中的协变和逆变,我们使用+ 来表示协变类型:使用-表示逆变类型:非转化类型不需要添加标记. 假如我们定义一个cla ...
- 不变(Invariant), 协变(Covarinat), 逆变(Contravariant) : 一个程序猿进化的故事
阿袁工作的第1天: 不变(Invariant), 协变(Covarinat), 逆变(Contravariant)的初次约 阿袁,早!开始工作吧. 阿袁在笔记上写下今天工作清单: 实现一个scala类 ...
- 从底层实现剖析Kotlin协变与逆变的原理
继续还是探究协变与逆变,在正式开始之前,先来对Kotlin和Java的协变与逆变进行一个对比: 1.Kotlin是声明处协变:而在Java中是在使用处协变: 如何理解,我们先来回顾一下在Java使用协 ...
- C#4.0泛型的协变,逆变深入剖析
C#4.0中有一个新特性:协变与逆变.可能很多人在开发过程中不常用到,但是深入的了解他们,肯定是有好处的. 协变和逆变体现在泛型的接口和委托上面,也就是对泛型参数的声明,可以声明为协变,或者逆变.什么 ...
随机推荐
- 手机浏览网页或打开App时莫名弹出支付宝领红包界面的原因及应对措施
自从支付宝推出扫码领红包活动后,这种模式独特的赏金机制,短时间内吸引了大量的关注,但是随之也产生了很多的问题,比由于如在赏金的驱动下,微信群里铺天盖地的红包口令,朋友圈里各式各样的领红包二维码图片, ...
- 12-7jquery选择器学习
p:odd 选择奇数个数的p标签 p:even选择奇数个数的p标签 p:gt(n)选择下标 大于n的p标签 p:lt(n)选择下标小于n的p标签 $(":root " ...
- 【BZOJ1477】青蛙的约会(拓展欧几里得)
[BZOJ1477]青蛙的约会(拓展欧几里得) 题面 题目描述 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为 ...
- [BZOJ1707] [Usaco2007 Nov] tanning分配防晒霜 (贪心)
Description 奶牛们计划着去海滩上享受日光浴.为了避免皮肤被阳光灼伤,所有C(1 <= C <= 2500)头奶牛必须在出门之前在身上抹防晒霜.第i头奶牛适合的最小和最 大的SP ...
- 开发中使用mongoTemplate进行Aggregation聚合查询
笔记:使用mongo聚合查询(一开始根本没接触过mongo,一点一点慢慢的查资料完成了工作需求) 需求:在订单表中,根据buyerNick分组,统计每个buyerNick的电话.地址.支付总金额以及总 ...
- UWP:记录一下这几天踩到的坑
最近在玩微软的Desktop Bridge项目,遇到了如下几个坑: 1.文档中给的是js项目魔改的方法,其实C#项目也可以魔改加入UWP部分的,区别在于: 不用在项目文件里写<AppxGener ...
- 如何使用Git以及GitHub
Git在程序的版本控制上有着极大的优势,下面是简单对其的简介 Git 的特点: 1 Snapshots, Not Differences 直接记录快照而非差异对比. 传统的版本控制系统(version ...
- Unity3D 心跳检测
在B/S结构的项目开发的过程当中 在服务端与客户端正常的通信之外 服务端通常还需要知道客户端是否还处于连接状态 或者客户端也需要知道服务端是否还处在开启状态 大白话说完了,听一下比较正统的解释吧(摘自 ...
- PHP实现发送模板消息到微信公众号
简述:在这里会具体讲述到如何实现:如何通过后台的代码来实现发送模板消息到已经关注了"心想"公众号的用户. (本人新手,目前实习中,我的所有文档都是在自己开发过程中的记录,有些言语跟 ...
- Online Judge(OJ)搭建——5、配置
Spring 配置一些本地类,还有 HTML form 提交文件的解析器. package per.piers.onlineJudge.config; import org.springframewo ...