在Scala里,Nothing是所有类的子类,是最低层的子类。那Scala中需要Nothing的目的何在呢?
Scala中用类型推演确定表达式和函数的类型。如果推演出的类型过于宽泛,则无助于类型校验。与此同时,如果一个分支返回Int,另一个分支抛出异常,那么在这样的情况下,将类型推演为Int会比通用的Any更有用!也就是说,抛出的异常必须推演为返回Int或是Int的子类型,以得到兼容。
不过,任何地方都可能抛出异常,并非所有的表达式都可以推演为Int。Scala用Nothing类型--所有类型的子类--帮助类型推演更平滑的工作。既然它是任何类型的子类,它就可以替换任何东西。Nothing是抽象的,因此,在运行时,它的实例病不会真实存在。它纯粹是类型推演的帮手。
下面是一个抛出异常的方法,我们看一下Scala如何推演类型:
方法madMethod()只是抛出一个异常,使用反射可以查询到这个方法的返回类型,结果如下:
scala.runtime.Nothing$
Scala的Nothing实际上有些非同寻常--它是所有其他类型的子类型。这样一来,Nothing就可以替换为Scala里的任何东西
Scala中用类型推演确定表达式和函数的类型。如果推演出的类型过于宽泛,则无助于类型校验。与此同时,如果一个分支返回Int,另一个分支抛出异常,那么在这样的情况下,将类型推演为Int会比通用的Any更有用!也就是说,抛出的异常必须推演为返回Int或是Int的子类型,以得到兼容。
不过,任何地方都可能抛出异常,并非所有的表达式都可以推演为Int。Scala用Nothing类型--所有类型的子类--帮助类型推演更平滑的工作。既然它是任何类型的子类,它就可以替换任何东西。Nothing是抽象的,因此,在运行时,它的实例病不会真实存在。它纯粹是类型推演的帮手。
下面是一个抛出异常的方法,我们看一下Scala如何推演类型:
def madMethod() = {throw new IllegalArgumentException()}
println(getClass().getDeclaredMethod("madMethod", null).
getReturnType().getName())
方法madMethod()只是抛出一个异常,使用反射可以查询到这个方法的返回类型,结果如下:
scala.runtime.Nothing$
Scala的Nothing实际上有些非同寻常--它是所有其他类型的子类型。这样一来,Nothing就可以替换为Scala里的任何东西