什么是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?
,意思是Nothing
或null
。 它有0 + 1个可能的值。 那么null
有一种Nothing?
。 Nothing?
可以被强制为任何可空类型,所以你可以做这样的东西:
var name: String? = null
这里null : Nothing?
被强制为String?
。
出于某种原因,不幸的是, 在stdlib中定义了这个函数 :
operator fun String?.plus(other: Any?): String
允许null + null
利用上面提到的那些强制规则