在kotlin中什么是空的以及为什么我可以';不要用它引起NPE?
查看在Kotlin REPL中运行的以下代码:在kotlin中什么是空的以及为什么我可以';不要用它引起NPE?,kotlin,Kotlin,查看在Kotlin REPL中运行的以下代码: >>> null.takeIf({1==2}) res4: kotlin.Nothing? = null 为什么这不会导致NullPointerException?Kotlin类型设计方法旨在故意消除NPE。如文档所示,可能触发的条件仅限于: 对抛出NullPointerException()的显式调用 使用!!下文所述的操作员 与初始化有关的某些数据不一致,例如: 构造函数中未初始化的this被传递并在某处使用(“泄漏th
>>> null.takeIf({1==2})
res4: kotlin.Nothing? = null
为什么这不会导致NullPointerException?Kotlin类型设计方法旨在故意消除NPE。如文档所示,可能触发的条件仅限于:
- 对抛出NullPointerException()的显式调用李>
- 使用!!下文所述的操作员李>
- 与初始化有关的某些数据不一致,例如:
- 构造函数中未初始化的this被传递并在某处使用(“泄漏this”)李>
- 超类构造函数调用其在派生类中的实现使用未初始化状态的开放成员李>
- Java互操作:
- 尝试访问平台类型的空引用上的成员李>
- 用于Java互操作的泛型类型具有不正确的nullability,例如,一段Java代码可能会将null添加到Kotlin MutableList中,这意味着应该使用MutableList来处理它李>
- 外部Java代码引起的其他问题
vall=b!!。长度
因此,如果你想要一个NPE,你可以拥有它,但是你
我们必须明确地要求它,而且它不会突然出现
因此,您的代码的行为符合预期。有关更多信息,请参阅链接
您的代码不会导致NullPointerException,因为
takeIf
是一个扩展函数。扩展函数被转换为方法接收器,第一个参数是调用函数的对象 因此,与
null.takeIf{false}
(简化示例)不同,您可能想知道为什么以下函数不抛出NullPointerException:
fun <T> takeIf(me: T, predicate: (T) -> Boolean): T? {
...
}
因此,如果您的谓词为false(如您的示例中,1==2
),它只会短路并返回null
如果它是真的
,那么呢?我们最终会得到一个空指针吗
没有:
因为NullPointerException在最微小的事情上是令人烦恼的,因为
takeIf
是一个扩展函数,而不是成员函数。“我猜编译器正在做一些优化,因为我们的null是一个常量。”你认为这有什么关系?只是谓词(this)
(在本例中{true}(null)
)返回true
,因此将返回this
(null
),但它不返回null
)。它返回Nothing
,这是标准库中定义的类。1。否,返回的值为null
。您可以测试它:nothing==null
为true。或者在问题中看到:=null
.2。类型是Nothing?
,而不是Nothing
,这就是为什么null
是一个合法值的原因。这个答案没有解释为什么代码会按预期运行。如何???它清楚地概述了导致Kotlin出现NPE的有限案例集,而这一问题并不适用。我是否也需要解释亚里士多德的逻辑,让它更清楚地说明这意味着什么是预期的行为?
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
return if (predicate(this)) this else null
}
val nothing: Nothing? = null.takeIf {
true
}