Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在kotlin中什么是空的以及为什么我可以';不要用它引起NPE?_Kotlin - Fatal编程技术网

在kotlin中什么是空的以及为什么我可以';不要用它引起NPE?

在kotlin中什么是空的以及为什么我可以';不要用它引起NPE?,kotlin,Kotlin,查看在Kotlin REPL中运行的以下代码: >>> null.takeIf({1==2}) res4: kotlin.Nothing? = null 为什么这不会导致NullPointerException?Kotlin类型设计方法旨在故意消除NPE。如文档所示,可能触发的条件仅限于: 对抛出NullPointerException()的显式调用 使用!!下文所述的操作员 与初始化有关的某些数据不一致,例如: 构造函数中未初始化的this被传递并在某处使用(“泄漏th

查看在Kotlin REPL中运行的以下代码:

>>> null.takeIf({1==2})
res4: kotlin.Nothing? = null

为什么这不会导致NullPointerException?

Kotlin类型设计方法旨在故意消除NPE。如文档所示,可能触发的条件仅限于:

  • 对抛出NullPointerException()的显式调用
  • 使用!!下文所述的操作员
  • 与初始化有关的某些数据不一致,例如:
    • 构造函数中未初始化的this被传递并在某处使用(“泄漏this”)
    • 超类构造函数调用其在派生类中的实现使用未初始化状态的开放成员
  • Java互操作:
    • 尝试访问平台类型的空引用上的成员
    • 用于Java互操作的泛型类型具有不正确的nullability,例如,一段Java代码可能会将null添加到Kotlin MutableList中,这意味着应该使用MutableList来处理它
    • 外部Java代码引起的其他问题
第三个选项适用于NPE爱好者:NOTNULL断言运算符 (!!)将任何值转换为非null类型,并在以下情况下引发异常: 该值为空。我们可以写b!!,这将返回一个非空值 b的值(例如,我们示例中的字符串),如果b为 空值:

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
}