写点什么

Scala 中的底类型(bottom types)

作者:小谷哥
  • 2022 年 4 月 18 日
  • 本文字数:919 字

    阅读完需:约 3 分钟

在 Scala 中存在两个比较特殊的类,Scala.Null 和 Scala.Nothing。它们是 Scala 面向对象的类型系统用于处理一些“极端情况”的特殊类型。

Null 类是 null 引用的类型,他是每个引用类(即继承自 AnyRef 的类)的子类,null 值可以用来给引用类初始化。但是 Null 并不兼容于值类型,即你不可能将 null 赋值给一个整数变量:

val i: Int = null

以上写法是不对的。

Nothing 位于 Scala 类继承关系的最底部,它是每个其他类型的子类型,并且,不存在这个类型的任何值。那么,Nothing 类型的意义何在呢?


  1. 作为参数类型。

在 Scala 的 List 中有一个特殊的存在,Nil,如果使用过 Nil 你就会发现,Nil 实际上就是一个 List[Nothing]。所以 Nil 可以与任何类型的元素进行集合的相关操作,例如 1 ::Nil,”abc” :: Nil,最终得到的集合结果会根据添加的元素类型决定,因为 Nothing 是任何类的子类,它可以被归为任何 List 中去。

  1. 非正常终止信号

在 Scala 中抛出异常跟 Java 一样,需要创建一个异常对象然后用 throw 关键字将它抛出:

throw new IllegalArgumentException

并且,在 Scala 中,抛出异常的动作 throw 是一个有结果类型的表达式,这个结果的类型就是 Nothing。如下示例:

val half:Int =

If ( n % 2 == 0)

n / 2

else

throw new RuntimeException(“n must be even”)

在这段代码中,如果 n 是偶数,那么 half 会被赋值为 n 的一半,如果 n 不是偶数那么 half 被初始化之前,就会有异常抛出。而你如此写不用担心 half 的类型问题,因为技术上讲,抛出异常这个表达式的类型是 Nothing。在这个场景下,if 的一个分支计算出某个值,而另一个分支抛出异常并计算出 Nothing,整个 if 表达式的类型就是那个计算出某个值的分支。

再举例来说,在 Scala 的标准类库中 Predef 对象有一个 error 方法,其定义如下:

def error(message:String):Nothing =

throw new RuntimeException(message)

error 方法的返回值类型是 Nothing,这告诉使用方该方法并不会正常返回,它会抛出异常。对 error 的使用如下:

def divide(x: Int, y: Int): Int =

if (y != 0) x / y

else error(“can’t divide by zero”)

这里的 x/y 条件判断的 then 分支的类型为 Int,而 else 分支类型为 Nothing,由于 Nothing 是 Int 的子类型,整个条件判断表达式的类型就是 Int,正如方法声明要求的那样。


关键词:大数据培训

用户头像

小谷哥

关注

定期分享编程相关技术知识 2022.02.16 加入

想要学习视频资料的可以自己关注尚硅谷B站官方账号

评论

发布
暂无评论
Scala中的底类型(bottom types)_小谷哥_InfoQ写作平台