闲话Scala中的Nothing与Null与Nil

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/daerzei/article/details/81773358

NothingNull是位于类型系统底层的两个特殊类型
其中Nothing是所有其他类型的子类,而Null是所有引用类型的子类

Null对于大多数语言而言是熟悉的概念。
尽管这些语言通常并没有定义Null类型,仅仅定义了关键字null
用于向引用变量赋值,表示该变量实际上没有值。
Null在编译器里的实现相当于以下声明:

package scala
abstract final class Null extends AnyRef

为何Null可以同时为finalabstract呢?
因为不允许子类派生以及创建实例,但运行时环境提供了一个实例,就是我们熟悉和喜爱的Null

Null被明确定义为AnyRef的一个子类型,但它也是所有AnyRef类型的子类型。
这是类型系统允许你用null给任何引用类型赋值的正常做法。
另一方面,因为null不是Anyval的子类型,所以不可以用null给Int赋值。
于是Scala的null与Java的null完全相同,
因为它必须与Java的null共存于JVM。
否则Scala会破坏null的概念,引起很多潜在的Bug

与此相反,Nothing在Java中没有类似的概念,但它填补了存在于Java类型系统中的空白。
Nothing在编译器里的实现相当于以下声明:

pacage scala
abstract final class Nothing extends Any

Nothing实际上继承了Any,根据类型系统里的构造规则,Nothing是所有其他类型的子类,
无论是引用类型不是值类型,换句话说,Nothing继承了所有一切。

不同于Null,Nothing没有实例。但Nothing为类型系统提供了两种功能,这有助于实现健壮且类型安全的设计。

Scala为空列表声明了一个专用的类型:Nil
在Java中Niil必须是像List那样的参数化类型,但是很不幸,根据定义Nil不包含任何元素,所以Nil[String]Nil[Any]是不同的类型,虽然实际上并无差别。
Nil的声明:

package scala.collection.immutable
object Nil extends List[Nothing] with Product with Serializable

NothingNull被称为底部的类型,因为它们处于类型层次结构的底端。也因为如此,它们是所有类型的子类。

Nothing的其他用途是:表示终止程序,
如抛出一下异常,

方法???的定义:

package scala
object Predef {
    ...
    def ??? : Nothing = throw enw NotImplementedError
    ...
}

由于???方法返回了Nothing,所以它可以被任何其他函数调用,无论该函数的返回值是什么。

scala.sys包定义了一个exit方法,用于程序的正常退出,
类似于Java中的System包的exit方法,
不过sys.exit返回的是Nothing
这意味着方声明为它返回 了一个正常的类型,但在必要的时候也可以调用sys.exit。并通过编译器类型检查。

猜你喜欢

转载自blog.csdn.net/daerzei/article/details/81773358