在 Java 中,null 是许多 Bug 的来源,一方面,null 并不是任何值或者类的实例,对 null 的任何调用都将抛出空指针异常(NullPointerException),另一方面 Java 程序员对于不返回值返回 null 的想法根深蒂固。这就导致在操作 Java API 时,经常由于忘记检查是否为空而导致程序崩溃,实在是一种不优雅的行为。而 Scala 就提供了优雅又易用的「空」,解决了这个苦恼的问题。
首先,Scala 摒弃了 Java 中如果方法没有返回值就返回 null 的规定,采用不会引发空指针异常的 Unit 代替:
所有值类型的子类,代表没有值
签名:final abstract class Unit private extends AnyVal
该类型同时具有抽象 + 最终修饰符,不能产生实例(编译阶段被审查)
一般用于函数定义中
系统为期预定义了实例:( )
val a: Unit = ()
即使一个返回值为 Unit 的函数被推断出实际返回的不是( ),也会被追加 ( )
// 比如:
val a: Unit = 2
// 实际上会被替换为:
val a: Unit = {
2
()
}
// 根据 scala 中最后一个值为返回值的原则,也就等同于:
val a: Unit = ()
( ).isInstanceOf[Unit]
的结果是 true
Scala 环境为中一个默认存在的 Unit 类实例:( )
参考 Unit
Unit 替代了返回类型 void,但绝大多数情况我们的方法是有返回值的,而且经常是可能有,也可能没有的情况,那么 None 就派上用场了,不过在此之前,我们先要了解 Nothing 这个特殊的类型:
abstract final class Nothing extends Any
case object None extends Option[Nothing]
对于其他集合,Scala 也提供了对应的空集合单例对象/获取方法:
object Nil extends List[Nothing] with Product with Serializable
object Empty extends Stream[Nothing]
override def empty[A]: 集合类型[A] = 对应空集合类型对象
作为 JVM 语言,Scala 提供了与 Java 互操作的类型 Null,以及相应实例 null,并作为关键字以便 Scala 开发者能更好处理两种代码之间的协作问题:
abstract final class Null extends AnyRef
不过其实对于 Java 代码返回的 Null,Option 类提供了一个构造方法 def apply[A](x: A): Option[A] = if (x == null) None else Some(x)
可以将 Java 传过来的可空对象转化为更易使用的 Option 对象。这下可以愉快的使用来自 Java 的 API 了。