在空引用上调用扩展函数时没有 NullPointerException
No NullPointerException when calling an extension function on null reference
我有点困惑为什么这段代码中没有任何地方抛出 NullPointerException
:
fun main() {
null.print()
}
fun <T> T.print() {
this.let { println(it) }
}
在 null
值上调用扩展函数 print
时没有编译器警告也没有异常,因为它是用不可为 null 的接收者类型定义的,调用 [= 时也没有异常14=] 在那个 null
引用上,即使 let
也有一个不可为 null 的接收者类型。这是什么原因?
对于扩展方法,kotlin 提供了语法糖。当您调用扩展方法时,kotlin 在这里所做的是在顶部提供包装器;这样通过使用它你可以获得调用者的实例。所以当你调用null.print()
时,它基本上是在下面调用print(null)
。
所以你可以想到下面的函数
fun <T> T.print()
转换为
fun <T> print(T t)
let 也一样,它是一个扩展方法,它实际上将 null
参数传递给 let
,而不是在 null
实例上调用 let
。
请注意,我是 kotlin 的新手,所以任何更正将不胜感激。
我有点困惑为什么这段代码中没有任何地方抛出 NullPointerException
:
fun main() {
null.print()
}
fun <T> T.print() {
this.let { println(it) }
}
在 null
值上调用扩展函数 print
时没有编译器警告也没有异常,因为它是用不可为 null 的接收者类型定义的,调用 [= 时也没有异常14=] 在那个 null
引用上,即使 let
也有一个不可为 null 的接收者类型。这是什么原因?
对于扩展方法,kotlin 提供了语法糖。当您调用扩展方法时,kotlin 在这里所做的是在顶部提供包装器;这样通过使用它你可以获得调用者的实例。所以当你调用null.print()
时,它基本上是在下面调用print(null)
。
所以你可以想到下面的函数
fun <T> T.print()
转换为
fun <T> print(T t)
let 也一样,它是一个扩展方法,它实际上将 null
参数传递给 let
,而不是在 null
实例上调用 let
。
请注意,我是 kotlin 的新手,所以任何更正将不胜感激。