Scala学习十七——类型参数
一.本章要点
- 类、特质、方法和函数都可以有类型参数
- 将类型参数放置在名称之后,以方括号括起来
- 类型界定的语法为T<:UpperBound、T>:LowerBound、T<%ViewBound、T:ContextBound
- 可以用类型约束来约束一个方法,比如(implicit ev:T<:<UpperBound)
- 用+T(协变来表示某个泛型的子类型关系和参数T方向一致,或用-T(逆变)来表示方向相反
- 协变适用于表示输出的类型参数,比如不可表集合中的元素
- 逆变适用于表示输入的类型参数,比如函数参数
二.泛型类
和Java/C++一致,类和特质都可以带类型参数。在类的定义中,可以用类型参数来定义变量、方法参数、以及返回值类型。例:
class Pair[T,S]{val first:T,val secend:S}
三.泛型函数
函数和方法也可以带类型参数。例:
def getMiddle[T](a:Array[T])=a(a.length/2)
四.类型变量界定
对类型变量进行限制,例:
//错误
class Pair[T](val first:T,val secend:T)
//不知道first是否有compareTo方法
{def smaller=if(first.compareTo(secend)<0) first else secend
} //解决方法(比较简单,也可以指定一个下界)
class Pair[T<:Comparable[T]](val first:T,val secend:T){
def smaller=if(first.compareTo(secend)<0) first else secend
}
五.视图界定
”视图界定“,T<%V要求必须存在一个从T到V的隐式转换,如class Pair[T <% Comparable[T]],<%意味着T可以被隐式转换成Comparable[T]。。。
六.上下文界定
格式为T:M,其中M是一个泛型类,要求必须存在一个类型为M[T]的”隐式值“。
七.Manifest上下文界定
要实例化一个泛型的Array[T],需要一个Mainfest[T]对象(要想让基本类型的数组能工作,这是必须的),例:
def makePair(T:Mainfest)(first:T,secend:T){
val r=new Array[T](2);r(0)=first;r(1)=secend;r
}
注:如果T是Int,希望虚拟机中对应的是一个int[]数组,在Scala中,Array只不过是类库中提供的一个类,编译器并不对它做特殊处理,因此要编写一个泛型函数来构造泛型数组,需要传入Mainfest对象帮忙(因为在虚拟机中,泛型相关的信息是被抹掉的,只会有一个makePair方法,却要处理所有类型T)。
八.多重界定
类型变量可以同时有上界和下界,写法为T >:Lower <:Upper,不能同时有多个上界或多个下界,但能同时实现多个特质。
可以有多个视图特质:T%<Comparable[T]<%String
可以有多个上下文界定:T:Ordering:Mainfest
九.类型约束
提供的另一种限定类型的方式,总共有三种关系:
T=:=U
T<:<U
T<%<U
这些约束将会测试T是否等于U,是否是U的子类型,或是否能被视图(隐式)转换为U,要使用这样的约束,需要添加”隐式类型证明参数“。
类型参数可在泛型类中定义只能在特定条件下使用的方法,例:
class Pair[T](val first:T,val second:T){
def smaller(implicit ev:T<:<Ordered[T])=
if(first<second) first else second
}
类型约束的另一个用途是改进类型推断,例:
def firstLast[A,C<:Iterable[A](it:C)=(it.head,it.last)] //执行,推断出的类型参数[Nothing,List[Int]]不符合[A,C<:Iterable[A]]
firstLast(List(1,2,3))
十.型变
例:
def makeFriends(p:Pair[Person])
//如果用Pair[Student]作为参数调用makeFriends在缺省情况下是错误的,尽管Student是Person的子类,但Pair[Student]和Pair[Person]没有任何关系 //想要这样的关系,必须在Pair类中表明
//+号意味着该类型是T协变的(与T按同样的类型型变),即Student是Person的子类型=》Pait[Student]是Pair[Person]的子类型
class Pair[+T](val first:T,val second:T) //另一个方向的型变
trait Friend[-T]{
def befriend(someone:T)}
//可以是逆变的,Student是Person的子类型,Friend[Student]是Friend[Person]的超类型
class Person extends Friends[Person]
class Student extends Person
val susan=new Student
val fred=new Person
makeFriendWith(susan,fred)
//注:在一个泛型的类型声明里面,可以同时使用这两种型变
十一.协变和逆变点
通常而言,对于某个对象消费的值适用于逆变,而对于它产出的值则适用于协变。
在Scala中数组是不支持型变的,不能将Array[Student]转换为Array[Person],或者反过来会不安全。。。
十二.对象不能泛型
没法给对象添加类型参数,比如可变列表。。。
十三.类型通配符
在Java中,所有泛型类都是不可变的,可以使用通配符改变它们的类型。
可以在Scala中使用通配符。。。
十四.练习
Scala学习十七——类型参数的更多相关文章
- scala学习笔记-类型参数中协变(+)、逆变(-)、类型上界(<:)和类型下界(>:)的使用
转载自 fineqtbull http://fineqtbull.iteye.com/blog/477994 有位je上的同学来短信向我问起了Scala类型参数中协变.逆变.类型上界和类型下界的 ...
- Scala学习教程笔记三之函数式编程、集合操作、模式匹配、类型参数、隐式转换、Actor、
1:Scala和Java的对比: 1.1:Scala中的函数是Java中完全没有的概念.因为Java是完全面向对象的编程语言,没有任何面向过程编程语言的特性,因此Java中的一等公民是类和对象,而且只 ...
- 入门大数据---Scala学习
Scala是什么? Scala是一种基于函数式编程和面向对象的高级语言.它开发了Spark等大型应用.它和Java有效集成,底层也是支持JVM的. 它有六大特性: 无缝JAVA互操作 Scala在JV ...
- Scala学习资源
Scala学习资源: Scala官方网站:http://www.scala-lang.org/ Scala github:https://github.com/scala/scala Twitter ...
- 【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习
下了这本<大数据Spark企业级实战版>, 另外还有一本<Spark大数据处理:技术.应用与性能优化(全)> 先看前一篇. 根据书里的前言里面,对于阅读顺序的建议.先看最后的S ...
- 机器学习(三)--- scala学习笔记
Scala是一门多范式的编程语言,一种类似Java的编程语言,设计初衷是实现可伸缩的语言.并集成面向对象编程和函数式编程的各种特性. Spark是UC Berkeley AMP lab所开源的类Had ...
- 【Scala】Scala学习资料
Scala学习资料 java 树形 分类器_百度搜索 决策树分类器-Java实现 - CSDN博客 KNN分类器-Java实现 - CSDN博客 学习:java设计模式—分类 - 飞翔荷兰人 - 博客 ...
- Scala学习网址
scala学习网址为:https://twitter.github.io/scala_school/zh_cn https://www.zhihu.com/question/26707124
- Spark之Scala学习
1. Scala集合学习: http://blog.csdn.net/lyrebing/article/details/20362227 2. scala实现kmeans算法 http://www.t ...
随机推荐
- 7 AOP
AOP:Aspect Oriented Programming 面向切面编程.AOP是对面向对象编程的一种补充,在运行时动态地将代码切入到类的指定方法.指定位置的编程思想.将不同的方法的同一位置抽象成 ...
- linux系统安装Memcache
Linux系统安装memcached 首先要先安装libevent库. centos 下执行 yum install libevent libevent-devel 查看memcached 是否已经 ...
- jquery - 定义二维数组
var products = []; products.push({product_id: '1',count: 3},{product_id:'2',count: 6})
- SQL-W3School-高级:SQL VIEW(视图)
ylbtech-SQL-W3School-高级:SQL VIEW(视图) 1.返回顶部 1. 视图是可视化的表. 本章讲解如何创建.更新和删除视图. SQL CREATE VIEW 语句 什么是视图? ...
- ubuntu 命令行以及目录的显示改为英文
在安装ubuntu的时候原本以为把ubuntu改为中文的好理解一些,最后发现命令行的报错一边中文一边英文确实难受,也不宜于学习,所以想把命令行以及目录的显示都改为英文的,我是这样先把命令行的该为英文的 ...
- 图解 HTTP 笔记(三)—— HTTP 报文内的 HTTP 信息
本章主要讲解请求和响应是如何运作的 一.HTTP 报文 用于 HTTP 协议交互的信息被称为 HTTP 报文,客户端的 HTTP 报文叫做请求报文,服务器端的叫做响应报文. HTTP 报文大致可分为报 ...
- Spring Boot项目中MyBatis连接DB2和MySQL数据库返回结果中一些字符消失——debug笔记
写这篇记录的原因是因为我之前在Spring Boot项目中通过MyBatis连接DB2返回的结果中存在一些字段, 这些字段的元素中缺少了一些符号,所以我现在通过在自己的电脑上通过MyBatis连接DB ...
- linux LVM 系统盘扩容
1.fdisk /dev/sda2.输入n,开始创建新分区3.输入p4.输入w5.mkfs.ext4 /dev/sda36.pvcreate /dev/sda37.vgdisplay 查看VG nam ...
- 攻防世界WEB新手练习
0x01 view_source 0x02 get_post 这道题就是最基础的get和post请求的发送 flag:cyberpeace{b1e763710ff23f2acf16c2358d3132 ...
- HDU6582 Path【优先队列优化最短路 + dinic最大流 == 最小割】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6582 来源:2019 Multi-University Training Contest 1 题目大意 ...