我特别要求不可为空的类型Nothing
。
我确实知道这Nothing?
允许我们,例如,过滤null
以使重载明确,但我正在努力思考Nothing
有用的实例。
Nothing?
可以只有一个值,null
。所以Nothing
可以完全没有价值。重点是什么?为什么不简单地使用Unit
?
我特别要求不可为空的类型Nothing
。
我确实知道这Nothing?
允许我们,例如,过滤null
以使重载明确,但我正在努力思考Nothing
有用的实例。
Nothing?
可以只有一个值,null
。所以Nothing
可以完全没有价值。重点是什么?为什么不简单地使用Unit
?
Nothing
是对应的Any?
就像Any?
任何其他类型的基类型一样,是任何其他类型Nothing
的子类型(甚至是可为空的类型)。
知道了这一点,在下面的例子中就很清楚了,给s
定String
的名字是 a String?
。
val s = name ?: throw IllegalArgumentException("Name required")
throw
表达式返回,和的Nothing
公共基类型是。这就是我们想要的,因为这是我们想要使用的类型。String
Nothing
String
如果我们要使用Unit
而不是Nothing
通用的基本类型将是Any
,这肯定不是我们想要的,因为它需要在String
之后进行强制转换。
这也是有道理的,因为如果抛出异常,则无法继续执行,因此s
无论如何都不会进一步使用。
Nothing
标记永远无法到达的代码位置fun foo() {
throw IllegalArgumentException("...")
println("Hey") // unreachable code
}
如果null
用于初始化推断类型的值并且没有其他信息可以确定更具体的类型,则推断类型将为Nothing?
.
val x = null // 'x' has type `Nothing?`
val l = listOf(null) // 'l' has type `List<Nothing?>
Nothing
用于告诉编译器它永远不会返回。例如,
fun main() {
var name: String? = null
val notNullName = name ?: fail("name was null")
println(notNullName)
}
fun fail(message: String): Nothing {
throw RuntimeException(message)
}
fun infiniteLoop(): Nothing {
while (true) {
// Nothingness
}
}