Kotlin println()重载解析模糊性



我有这个代码示例

var n: String? = "I am nullAble"
n = null
var nonNullName : String = "I cannot be null"
n?.let {
println(nonNullName)        // 1 -- OK

nonNullName = n
println(nonNullName)       //! 2 -- Kotlin: Overload resolution ambiguity

var v1 : String = n
println(v1)                 // 3 -- OK
}

有人能向我解释为什么第二个";println(nonNullName(";不能通过编译器;println(v1(";还好吗
以下是来自IntelliJ IDEA 的错误消息

Kotlin: Overload resolution ambiguity:  
public inline fun println(message: Any?): Unit defined in kotlin.io  
public inline fun println(message: Boolean): Unit defined in kotlin.io  
public inline fun println(message: Byte): Unit defined in kotlin.io  
public inline fun println(message: Char): Unit defined in kotlin.io  
public inline fun println(message: CharArray): Unit defined in kotlin.io  
public inline fun println(message: Double): Unit defined in kotlin.io  
public inline fun println(message: Float): Unit defined in kotlin.io  
public inline fun println(message: Int): Unit defined in kotlin.io  
public inline fun println(message: Long): Unit defined in kotlin.io  
public inline fun println(message: Short): Unit defined in kotlin.io  

这似乎是Kotlin类型检查器早期版本中的一个错误,可能与无法访问的代码检测交互不好。

这个错误毫无意义:nonNullName显然是String,这既是因为它是显式声明的,也是因为IDE的类型检查确认显式类型是冗余的。它不可能与任何其他println函数签名相匹配。

删除n = null行会使错误消失,这不会影响任何变量的类型信息。

进一步强化了这是一个错误的想法,当Kotlin版本设置为1.4.10或1.4.20时,它在play.kotlinlang.org上的官方在线编码环境中运行良好,但在Kotlin 1.3.72上中断。

要修复它,请确保您使用的是最新版本的Kotlin。

我想编译器对这段代码有点困惑。一方面,您将n设置为null,这意味着n?.let { ... }块内的代码将不会执行。另一方面,当您在块n?.let { ... }内时,假设n不是null。这在n的类型分辨率中产生了不确定性,因为它被认为同时是nullnon-null。当您指定nonNullName = n时,该不确定性将传递给nonNullName

最新更新