Scala的存在类型
Scala的存在类型
存在类型也叫existential type,是对类型做抽象的一种方法。可以在你不知道具体类型的情况下,就断言该类型存在。
存在类型用_来表示,你可以把它看成java中的?。
下面是存在类型的具体例子:
| 简写 | 完整形式 | 描述 |
|---|---|---|
| Seq[_] | Seq[T] forSome {type T} | T 可以是Any 的任意子类 |
| Seq[_ <: A] | Seq[T] forSome {type T <: A} | T 可以是A(在某处已经定义了)的任意子类 |
| Seq[_ >: Z <: A] | Seq[T] forSome {type T >: Z <: A} | T 可以是A 的子类且是Z 的超类 |
上面的表格以常用的Seq为例,列举了存在类型的例子。
那么为什么会需要存在类型呢?
如果我们有一个List[A],我们需要两个版本的double函数,一个版本接受List[Int]并返回新的List[Int]*2,另外一个版本接受List[String], 并通过对整数调用toInt,将字符串转换为Int,然后调用第一个版本的double函数。
我们可能会这样写:
object Doubler {
def double(seq: Seq[String]): Seq[Int] = double(seq map (_.toInt))
def double(seq: Seq[Int]): Seq[Int] = seq map (_*2)
}
上面的程序看起来是没问题的,但是编译却失败。
Error:(3, 7) double definition:
def double(seq: Seq[String]): Seq[Int] at line 12 and
def double(seq: Seq[Int]): Seq[Int] at line 13
have same type after erasure: (seq: Seq)Seq
def double(seq: Seq[Int]): Seq[Int] = seq map (_*2)
问题就在于编译过程中的类型擦除,也就是在编译成字节码过后,定义的泛类型将会被删除。那么最后Seq[String]和Seq[Int]都会被编译成Seq,最终导致两个方法拥有同样的参数列表,最终编译报错。
既然有类型擦除的问题,那么我们考虑定义一个double方法,在double方法内部进行类型的判断:
object Doubler {
def double(seq: Seq[_]): Seq[Int] = seq match {
case Nil => Nil
case head +: tail => (toInt(head) * 2) +: double(tail)
}
private def toInt(x: Any): Int = x match {
case i: Int => i
case s: String => s.toInt
case x => throw new RuntimeException(s"Unexpected list element $x")
}
}
为什么我们需要使用Seq[_]呢? 我们看一下Seq类型的定义:
type Seq[+A] = scala.collection.Seq[A]
从定义我们知道,Seq类型一定是需要一个类型参数的,如果我们这样写:
def double(seq: Seq): Seq[Int] = seq match {
case Nil => Nil
case head +: tail => (toInt(head) * 2) +: double(tail)
}
则会编译出错,因为tail是Seq[A]类型的,但是double需要一个Seq类型。
使用Seq[_]表示,Seq[T] forSome {type T}。虽然我不知道Seq里面具体是哪种类型,但是肯定是有类型的。
可以对比一下java.
util.List[_ <: A] 的表达式在结构上与Java 的表达式java.util.List<? extends A>的类似之处。
你会在scala代码中看到很多Seq[_]的代码,存在类型的主要目的是为了兼容java代码。
更多教程请参考 flydean的博客
Scala的存在类型的更多相关文章
- 第54讲:Scala中复合类型实战详解
今天学习了scala的复合类型的内容,让我们通过实战来看看代码: trait Compound_Type1trait Compound_Type2class Compound_Type extends ...
- 第53讲:Scala中结构类型实战详解
今天学习了scala的结构类型,让我们看看代码 class Structural {def open() = print("A class interface opened") } ...
- Scala 深入浅出实战经典 第54讲:Scala中复合类型实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Scala 深入浅出实战经典 第53讲:Scala中结构类型实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Scala的Option类型
Scala的Option类型 为了让所有东西都是对象的目标更加一致,也为了遵循函数式编程的习惯,Scala鼓励你在变量和函数返回值可能不会引用任何值的时候使用Option类型.在没有值的时候,使用No ...
- 【scala】基础类型
基础类型 位数 Boolean - Byte ...
- scala如何解决类型强转问题
scala如何解决类型强转问题 scala属于强类型语言,在指定变量类型时必须确定数据类型,即便scala拥有引以为傲的隐式推到,这某些场合也有些有心无力. 例如: java同属强类型语言,但java ...
- Scala的Higher-Kinded类型
Scala的Higher-Kinded类型 Higher-Kinded从字面意思上看是更高级的分类,也就是更高一级的抽象.我们先看个例子. 如果我们要在scala中实现一个对Seq[Int]的sum方 ...
- Scala的自定义类型标记
Scala的自定义类型标记 Scala中有很多千奇百怪的符号标记,看起来是那么的独特,就像是一杯dry martini-好像黑夜中的萤火虫,那么耀眼,那么出众. 好了言归正传,这一篇文章我们会讲一下S ...
随机推荐
- Ubuntu命令方式安装中文语言包
Ubuntu命令方式安装中文语言包 安装之前执行 $LANG 查看语言环境 中文语言包: language-pack-zh-hans 简体中文 language-pack-zh-hans-base l ...
- ajax使用POST提交报错400
并非BadRequest!! 在用ajax访问登录接口的时候出现了这个错误,查阅得到使用Ajax的Post需要添加 contentType: "application/x-www-form- ...
- Linux利器:使用 gcc 编程C程序
文章更新于:2020-03-23 文章目录 一.手动编译链接单个C源文件 1.创建C源文件 2.编译源文件 3.生成可执行文件 二.手动编译链接多个C源文件 1.创建两个C源文件 2.编译两个源文件 ...
- 简单分析ucenter 会员同步登录通信原理
1.用户登录discuz,通过logging.php文件中的函数uc_user_login对post过来的数据进行验证,也就是对username和password进行验证. 2.如果验证成功,将调用位 ...
- Spring XML Bean 定义的加载和注册
前言 本篇文章主要介绍 Spring IoC 容器怎么加载 bean 的定义元信息. 下图是一个大致的流程图: 第一次画图,画的有点烂.
- 数据结构-Python 字典
字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示 d = ...
- 2、使用断言(json assertion)
1.假设现在有一个服务端的返回数据(需要测试的)为:HTTP/1.1 200 OK,要测试的响应字段勾选Response Headers,模式匹配规则选择Substring,把该响应断言命名为Http ...
- 内存对齐 align
/* 地址对齐:指的是存放数据的首地址%N==0,而且整个结构体的大小%M(结构体的有效对齐值)==0 1 数据类型的自身对齐值:char:1 short:2 int,flolat,double:4 ...
- Mybatis对象关系映射 one2one,one2many,many2many
MyBatis中的高级映射一般要借助select元素中的resultMap属性进行实现,通过此属性配置实现一对一,一对多等关系映射的实现 一对一映射:association 一对多映射:collect ...
- 给学妹的 Java 学习路线
大家好,这篇文章主要是讲解下如何自学 Java,这个问题有很多粉丝私信问过,今天又有直系学妹问我如何学习 Java? 我就以我的经历,总结下分享给大家,有不当指出或者有更好的方法建议也欢迎留言指出,大 ...