Scala Nothing

Scala Nothing教程

Scala 中的 Nothing 类型表示类层级的最底端,它是任何其他类型的子类型。

在 Scala 中,Nothing 可以作为没有正常返回值的方法的返回类型,非常直观的告诉你这个方法不会正常返回,而且由于Nothing是其他任意类型的子类,他还能跟要求返回值的方法兼容。

Scala Nothing使用

Nothing 主要有两个作用,第一,可以用于类型参数,第二可以用于代表非正常退出,比如抛异常。

类型参数

首先,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。

Scala Nothing总结

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