Kotlin 在null引用上调用扩展函数时无NullPointerException

Kotlin 在null引用上调用扩展函数时无NullPointerException,kotlin,null,Kotlin,Null,我有点困惑,为什么在这段代码中没有抛出NullPointerException: fun main() { null.print() } fun <T> T.print() { this.let { println(it) } } fun main(){ null.print() } 文{ this.let{println(it)} } 在null值上调用扩展函数print时,没有编译器警告或异常,因为它是用不可为空的接收器类型定义的;在null引用上调用let时

我有点困惑,为什么在这段代码中没有抛出
NullPointerException

fun main() {
   null.print()
}

fun <T> T.print() {
    this.let { println(it) }
}
fun main(){
null.print()
}
文{
this.let{println(it)}
}

null
值上调用扩展函数
print
时,没有编译器警告或异常,因为它是用不可为空的接收器类型定义的;在
null
引用上调用
let
时,也没有异常,即使
let
也有不可为空的接收器类型。原因是什么?

对于扩展方法,kotlin提供了一个语法糖。当您调用扩展方法时,kotlin在这里做的是在顶部提供包装器;因此,通过使用它,您可以获得调用者的实例。因此,当您调用
null.print()
时,它基本上是在下面调用
print(null)

因此,您可以考虑以下函数

fun <T> T.print()
fun T.print()
转化为

fun <T> print(T t)
fun打印(T)
let也是如此,它是一种扩展方法,实际上是将
null
参数传递给
let
,而不是在
null
实例上调用
let


请注意,我是kotlin的新手,因此任何更正都将不胜感激。

对于扩展方法,kotlin提供了一个语法糖。当您调用扩展方法时,kotlin在这里做的是在顶部提供包装器;因此,通过使用它,您可以获得调用者的实例。因此,当您调用
null.print()
时,它基本上是在下面调用
print(null)

因此,您可以考虑以下函数

fun <T> T.print()
fun T.print()
转化为

fun <T> print(T t)
fun打印(T)
let也是如此,它是一种扩展方法,实际上是将
null
参数传递给
let
,而不是在
null
实例上调用
let


请注意,我是kotlin的新手,因此任何更正都将不胜感激。

“使用不可为空的接收器类型定义”,不,
相同,因此接收器可以为空“使用不可为空的接收器类型定义”,不,
相同,因此接收器可以为空