什么是kotlin中的null + null类型?

x是什么类型,为什么是String

 val x = null + null 

这是否是一些黑客?

将此字符串与给定的[other]对象的字符串表示形式连接起来。 如果receiver *或[other]对象为null,则表示为字符串“null”。 (c)Library.kt

可能是因为String?.plus(Any?)是Kotlin库中唯一一个接受可空类型作为接收者的函数。 因此,当你调用null + null ,编译器会把第一个null当作String?

如果你定义一个接收器类型为Int?的扩展函数Int? 并且返回类型是Int ,那么x将被推断为Int

 public operator fun Int?.plus(other: Any?): Int = 1 val x = null + null 

如果你在同一个文件中声明了另一个类似的函数(可以是接收者类型的空类型),当你调用null + null ,会导致编译时错误: Overload resolution ambiguity. All these functions match. Overload resolution ambiguity. All these functions match.

 public operator fun Int?.plus(other: Any?): Int = 1 public operator fun Float?.plus(other: Any?): Float = 1F val x = null + null //compile time error 
 val x = null + null 

尝试重写这个如下,你会发现你回答:

 val x = null.plus(null) 

下面是IntelliJ显示的plus方法的签名:

 public operator fun String?.plus(other: Any?): String 

所以第一个null被视为String? 键入,然后当你尝试加上其他任何东西时,上面的plus是你唯一的匹配。 打印x将导致nullnull

我们需要从Nothing的类型开始。 该类型具有完全为零的可能值。 它是一个底部类型 ,是每个其他类型的子类型(不要与Any 其他类型的超类型混淆)。 Nothing都不能强制任何类型,所以你可以做这样的事情:

 fun doStuff(a: Int): String = TODO("this typechecks") 

转到Nothing?的类型Nothing? ,意思是Nothingnull 。 它有0 + 1个可能的值。 那么null有一种Nothing?Nothing? 可以被强制为任何可空类型,所以你可以做这样的东西:

 var name: String? = null 

这里null : Nothing? 被强制为String?

出于某种原因,不幸的是, 在stdlib中定义了这个函数 :

 operator fun String?.plus(other: Any?): String 

允许null + null利用上面提到的那些强制规则