Desugar Scala(16) -- Lower Bound
欢迎关注我的新博客地址:http://cuipengfei.me/
Lower bound,不知道这个词的确切中文翻译是怎样的。我们直接看例子吧。
1 |
|
我们定义一个叫做Pair的类,其中可以包含两个元素,元素类型为泛型的T。
Pair类中有一个replaceFirst方法,用来把第二个元素和一个新的元素结合起来组成一个新的Pair。新的元素的类型是泛型的R。新组成的Pair的类型是Pair[R]。
到这里我们就要想了,一个T和一个R,它们俩怎么组成新的Pair呢?新的Pair的类型怎么能是Pair[R]呢?
replaceFirst的签名给我们说明了这一点。[R >: T]。这种标记的含义是说R是T的基类。那么一个T和一个R自然可以组合成一个R的Pair了。
单是这样干说,有点不好理解,我们看一个例子:
1 |
|
汽车和坦克都是机动车。
然后我们可以这样使用它们:
1 |
|
首先我们用两辆汽车组成一个Pair,其类型为Pair[Car]。
然后我们用一辆坦克替代原来的Pair中的第一个元素,让坦克和第二辆车组成一个新的Pair。新的Pari的类型是Pair[Vehicle]。
这里有一点tricky。我们调用replaceFirst的时候传递的参数的类型是Tank,这是否意味着在这里R就是Tank呢?
不是的,因为很明显Tank不是Car的基类,然而Tank是一个(is a)Vehicle,Vehicle同时也是Car的基类。于是此处的R就是Vehicle。得到的新的Pair自然就是Pair[Vehicle]。
也就是说R会被什么具体类型替换呢?这取决于T和newFirst的类型。
如果newFirst的类型刚好是T的基类,那太好了,R就直接是newFirst的类型。如果newFirst的类型不是T的基类,那R就会是T和newFirst的类型的共同基类。
这个东西挺麻烦的,它有啥用呢?
保证类型安全,Java没有提供给我们的类型安全。
还是刚才的那段代码:
1 |
|
其中的第二行,Scala可以很聪明的推断出replaceFirst的返回值类型是Pair[Vehicle]。实际上,如果我们试图把tankAndCar声明为Pair[Tank]的话,会看到编译时错误。
而类似的代码在Java里则没有这么幸运了:
1 |
|
为了标明区别,我们这次称之为PairJ。到这里忍不住要小小的黑Java一下,21行代码,和Scala的3行是等价的:)
我们重点看一下replaceFirst在这里的声明,其中声明了一个泛型参数R,但是R和T是没有任何关系的。实际上,在Java中,我们无法表达方法的泛型参数和类型的泛型参数之间的关系。(其原因请参看这里)
我们写出如下的代码:
1 |
|
先创建两辆车的Pair,然后把第一辆车替换成坦克。再把新组成的Pair里面的第二个元素(其类型是车)取出来,赋值给一个类型为坦克的变量。
如果我们编译这段代码,Java编译器会允许其通过。但是运行起来就会跑出类型转换异常。原因很明显,Car不能转换成Tank。
这个,就是刚才所说的类型安全性上的差异。
等等,脱衣服的部分呢?
之前的每一篇博客都会把Scala代码编译出的bytecode反编译成Java,来探索其语言特性是如何实现的。
而这一次颇为不同。之前的语言特性虽说Scala写起来比Java会简便一些,但是还没有超出Java的能力范围。多费点劲,用Java还是能做到。
而这一次,这种编译时类型安全检验的严格性,实在是在Java中无法表达的。这全靠了Scala编译器的功劳。
这就意味着,上面所定义的Pair这个类,如果你在Java中使用它,就会失去这种类型安全性。
Scala,这次算你牛,没扒掉你。
Desugar Scala(16) -- Lower Bound的更多相关文章
- Desugar Scala(15) -- unapply和unapplySeq方法
欢迎关注我的新博客地址:http://cuipengfei.me/ 实在想不到什么动词可以当做脱衣服来讲了,所以从现在开始这系列博文就叫做Desugar Scala了.除非哪天才思泉涌,又想到了新词: ...
- Scala - 语言专家 - Desugar Scala code
https://mp.weixin.qq.com/s/zwrG1MfUzXwtik7jotpQsA 介绍Intellij IDEA中的一个去除Scala语法糖的功能. 1. 去除 ...
- 二分查找里的upper bound与lower bound的实现与分析
1. 问题引入 最近参选了学堂在线的课程数据结构(2015秋).课程由清华大学的邓俊辉老师主讲,在完成课后作业时,遇到了这样一个题目范围查询.在这个题目中,我需要解决这样一个子问题:给定了一组已经排好 ...
- ELBO surgery: yet another way to carve up the variational evidence lower bound
目录 概 主要内容 Evidence minus posterior KL Average negative energy plus entropy Average term-by-term reco ...
- Desugar Scala(17) -- Option和for,以及脑子里发生的事情
欢迎关注我的新博客地址:http://cuipengfei.me/blog/2014/08/30/options-for/ Scala里的forkeyword是个非常有趣的东西. 能够用来把多层嵌套f ...
- [Bayes] KL Divergence & Evidence Lower Bound
L lower是什么? L lower, 既然大于,那么多出来的这部分是什么?如下推导: 得出了KL的概念,同时也自然地引出了latent variable q.
- 关于upper、lower bound 的探讨
lower_bound(A, A+n, x) - A 返回第一个大于等于x的数的下标 lower_bound(A, A+n, x) - A - 1 返回最后一个小于x的数的下标 upper_boun ...
- my understanding of (lower bound,upper bound) binary search, in C++, thanks to two post 分类: leetcode 2015-08-01 14:35 113人阅读 评论(0) 收藏
If you understand the comments below, never will you make mistakes with binary search! thanks to A s ...
- Beginning Scala study note(8) Scala Type System
1. Unified Type System Scala has a unified type system, enclosed by the type Any at the top of the h ...
随机推荐
- 机器学习实战之PCA
1. 向量及其基变换 1.1 向量内积 (1)两个维数同样的向量的内积定义例如以下: 内积运算将两个向量映射为一个实数. (2) 内积的几何意义 如果A\B是两个n维向量, n维向量能够等价表示为n ...
- Number Sequence_hdu_1005(规律)
9329854 2013-10-13 14:36:41 Accepted 1005 171MS 5072K 654 B Java zhangyi http://acm.hdu.edu.cn/showp ...
- 桥(Bridge)模式
Bridge定义:将抽象和行为划分开来,各自独立,但能动态的结合. 为什么使用桥模式 通常,当一个抽象类或接口有多个具体实现(concrete subclass),这些concrete之间关系可能有以 ...
- taro 打包微信小程序运行失败(二)
1.报错信息 thirdScriptError sdk uncaught third Error Cannot read property 'dispatch' of null TypeError: ...
- pselect 和 select
pselect函数是由POSIX发明的,如今许多Unix变种都支持它. #include <sys/select.h> #include <signal.h> #include ...
- iOS 全屏侧滑/UIScrollView/UISlider间滑动冲突
代码地址如下:http://www.demodashi.com/demo/13848.html 效果预览 一.前期准备 有一个支持全屏侧滑返回的视图控制器ViewController,ViewCont ...
- spring 发送邮件问题
public void sendEmail() throws Exception { JavaMailSenderImpl senderImpl = new JavaMailSenderImpl(); ...
- Linux命令-文件处理命令:ln
ln -s /etc/issue /tmp/issue.soft 为这个/etc/issue文件创建一个软连接,名称为/tmp/issue.soft(相当于windows里面给/etc/issue文件 ...
- 非变动性算法源代码分析与使用示例( for_each、min_element 、find_if、search 等)
非变动性算法代码分析与示例: 一.for_each C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // TEMPLATE FUNCTION for_eac ...
- 构造矩阵解决这个问题 【nyoj299 Matrix Power Series】
矩阵的又一个新使用方法,构造矩阵进行高速幂. 比方拿 nyoj299 Matrix Power Series 来说 给出这样一个递推式: S = A + A2 + A3 + - + Ak. 让你求s. ...