文档章节

Scala中的Nothing类型

SeekerLee
 SeekerLee
发布于 2014/07/03 15:56
字数 1008
阅读 615
收藏 0

初学Scala的时候会碰到一个奇怪的东西:Nothing。翻译的话叫“啥都没有”?这个Nothing到底是什么,有什么用?下面是我个人的一些见解。

  1. Nothing是什么

Nothing是一个类型(type)。就像Int、String一样是一个类型,比如值3是Int型的,值"abc"是String型的,与Int、String不同的是,不存在Nothing类型的值。

Nothing这个类型(Type)还有个特点,他是Bottom Type,所谓Bottom type就是他是所有其他类型的子类型(Sub Type) (The bottom type is a subtype of all types.)。 所以可以认为Nothing是Int的子类型,Nothing也是String的子类型。下面摘自Scala Reference 3.5.2 Conformance

For every value type T , scala.Nothing <: T <: scala.Any For every type constructor T (with any number of type parameters), scala.Nothing <: T <: scala.Any

  1. Nothing意义何在

意义之一:用于类型参数(covariant parameterized types)。 首先,Scala的泛型是不允许不加类型参数的。 以下摘自Programming In Scala, 2nd Edition, Chapter 19 Type Parameterization

Unlike Java, which allows raw types, Scala requires that you specify type parameters. (不像Java那样允许raw type,Scala必须指定类型参数)

所以以下两行会出错:Error: type List takes type parameters

type myList = List
val li: List = List(1)

改写成如下可以通过编译:

type myList = List[String]
val li: List[Int] = List(1)

因为List(1)有一个Int型的元素:1,所以他的类型是List[Int]。嗯,make sense,一个List的类型取决于这个List里面的元素。所以List("abc")那么就是List[String]型,List("abc", 1)就是List[Any],因为"abc"和1都是Any型的子类型。类型推导就是这么工作的。

那么List()呢?一个空的List,他是什么类型呢?肯定不是List[Int],因为里面并没有Int,也不是List[Any],因为里面啥都没有,没有理由推导出任何一个其他类型,于是这个List()只能是List[Nothing]。

scala> val l = List()
l: List[Nothing] = List()

Nil就是继承自List[Nothing]的。所以才可以做1 :: Nil和"abc" :: Nil。也正因为Nil是List[Nothing],Nothing是bottome type,List是协变的,所以1 :: Nill才会被推导成List[Int],"abc" :: Nil会被推导成List[String]

case object Nil extends List[Nothing] {
     override def isEmpty = true
     def head: Nothing =
       throw new NoSuchElementException("head of empty list")
     def tail: List[Nothing] =
       throw new NoSuchElementException("tail of empty list")
}

小实验,下面可以编译执行吗?ml1的类型是什么呢?

val ml: List[String] = List()
val ml1 = 2 :: ml

**意义之二,代表非正常退出。**比如抛异常。这个也很make sense,异常嘛,肯定啥都返回不了,类型只有是Nothing了。

scala> def e = throw new Exception("s")
e: Nothing

上文中的Nil的head方法也是一个例子。这里也体现了Nothing的Bottom Type的好处。

scala> def er(p: Boolean) = if(p) 1 else throw new Exception("yeah")
er: (p: Boolean)Int

类型推导观察了下程序,发现这个er方法有2种可能的返回类型,一种是Int,一种是Nothing。由于Nothing是Bottom Type,所以Nothing是Int的子类,所以认为这2种可能返回的类型都是Int,所以推导出er方法的返回值是Int。

说了这么多,Doc上就几句话:

Nothing is - together with scala.Null - at the bottom of Scala's type hierarchy.

Nothing is a subtype of every other type (including scala.Null); there exist no instances of this type. Although type Nothing is uninhabited, it is nevertheless useful in several ways. For instance, the Scala library defines a value scala.collection.immutable.Nil of type List[Nothing]. Because lists are covariant in Scala, this makes scala.collection.immutable.Nil an instance of List[T], for any element of type T.

Another usage for Nothing is the return type for methods which never return normally. One example is method error in scala.sys, which always throws an exception.

总结,Nothing是一个Bottom类型,不存在任何值属于Nothing类型。主要有2个用处,用于类型参数和代表非正常退出。

参考资料: 1: http://en.wikipedia.org/wiki/Bottom_type 2: http://www.scala-lang.org/docu/files/ScalaReference.pdf 3: http://www.scala-lang.org/api/2.10.4/index.html#scala.Nothing 4: Programming In Scala, 2nd Edition

© 著作权归作者所有

共有 人打赏支持
上一篇: Hello World
下一篇: Hello World
SeekerLee
粉丝 7
博文 2
码字总数 1012
作品 0
苏州
程序员
私信 提问
scala语言与java的区别

scala支持关联映射,如可以用(key -> value)表示一个键值对 scala中的所有类型都是对象,包括基本数据类型 scala中的case语句用来判断接收的消息,比java中的switch...case...更专注 receiv...

jhonephone
2014/09/03
0
0
【Spark亚太研究院系列丛书】Spark实战高手之路-第2章动手实战Scala第1小节(1)

1,在命令行和Scala IDE for Eclipse中动手体验Scala Scala一门基于JVM的面向对象和函数式编程相结合的静态语言,安装和运行Scala首先需要Java虚拟环境,直接到官方网站下载和安装Java即可:...

Spark亚太研究院
2014/11/22
0
0
写给Python程序员的Scala入门教程

随着业务和数据的需要,我们引入了。对的支持还是挺好的,但毕竟它还是使用开发的,且现有的API并没有100%覆盖Python。所以就有了这篇文章,让Python程序员可以接触这门更高(级)、更快(速...

羊八井
2015/11/29
906
2
写给Java程序员的Scala入门教程

(原文链接:http://www.yangbajing.me/2016/07/24/写给java程序员的scala入门教程/,转载请注明) 之前因为Spark的引入,写了一篇《写给Python程序员的Scala入门教程》。那篇文章简单对比了...

羊八井
2016/07/25
4.2K
20
Scala开发者的Spring-Boot快速上手指南 02:Scala惯用法

(这是一篇迟来的文章,从3月份计划到成文花了5个月多……以后需要避免这样的低效率。) 之前写第一篇文章时,只是想试试在Spring中使用Scala。但现在随着工作的需要,已经决定在应用层基于Spr...

羊八井
2016/10/12
134
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周三乱弹 —— 有一天考拉麻麻拉肚子了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @瘟神灬念 :分享周汇洋的单曲《Man Srae(曼斯拉之舞)》:美滋滋。。。。 手机党少年们想听歌,请使劲儿戳(这里) 我听了一下 赶紧关了, ...

小小编辑
今天
44
5
oh-my-zsh 自定义

GitHub 地址 基于 oh-my-zsh 的自定义配置,增加了一些个人常用插件与皮肤。 采用的是 git submodule 来维护,包括 oh-my-zsh,之所以这么搞,主要是手头有多台 linux 需要维护, 每台机器、...

郁也风
今天
6
0
Docker安装踩坑:E_FAIL 0x80004005的解决

参考 菜鸟教程--Windows Docker 安装 http://www.runoob.com/docker/windows-docker-install.html 官方文档-Install Docker Toolbox on Windows https://docs.docker.com/toolbox/toolbox_in......

karma123
今天
6
0
js垃圾回收机制和引起内存泄漏的操作

JS的垃圾回收机制了解吗? Js具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。 JS中最常见的垃圾回收方式是标记清除。 工作原理:是当变量进入环境时,将这个变量标记为“...

Jack088
昨天
18
0
大数据教程(10.1)倒排索引建立

前面博主介绍了sql中join功能的大数据实现,本节将继续为小伙伴们分享倒排索引的建立。 一、需求 在很多项目中,我们需要对我们的文档建立索引(如:论坛帖子);我们需要记录某个词在各个文...

em_aaron
昨天
27
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部