This question already has answers here:
Smart cast to 'Type' is impossible, because 'variable' is a mutable property that could have been changed by this time

(10 个回答)


2年前关闭。




第二个 println 错误:


fun main(args: Array<String>) {
    val r: Rectangle = Rectangle(5,5)
    println(r.isSquare)
    r.isSquare = true
    println(r.isSquare) // error but works with println(r.isSquare?:false)

}

data class Rectangle(var height: Int, var width: Int){
    var isSquare: Boolean? = null
}

如果它是空的,它会像第一个 println 一样打印空,为什么我必须这样做?

编辑 2

感谢您的所有回答,我现在明白了:
第一个 println 是
println(message: Any?)

第二个 println 是
println(message: Boolean)

因为 r.isSquare = true 使编译器相信 isSquare 是 boolean 值而不是 boolean 值?

Edit2

这是我如何处理编译器以保持信任 isSquare 是 boolean 值?
fun main(args: Array<String>) {
    val r: Rectangle = Rectangle(5, 5)
    println(r.isSquare)
    r.isSquare = true as Boolean? // if no cast, he will try wrong println signature
    println(r.isSquare)
}

data class Rectangle(var height: Int, var width: Int){
    var isSquare: Boolean? = null
}

最佳答案

由于 r.isSquare 是一个可变属性,编译器无法在空检查后将其智能转换为非空属性。

您可以使用 let :

r.isSquare.let { println(it) }
let 只读取一次 r.isSquare 的值,它提供与 lambda 中的 it 相同的值。因此,即使在空检查之后,您也不必使用 ?!! 来访问 boolean 值。

Kotlin spec :



第一个 println 使用这个 println(message: Any?)
由于您接下来将 true 分配给 isSquare,当您尝试打印时,编译器会尝试将 isSquare 智能转换为 Boolean 类型。但它不能智能转换,因为该属性是可变类型。

如果删除行 r.isSquare = true ,则编译器不会尝试将其智能转换为 Boolean 并使用 printlnAny? 作为参数。

关于kotlin - 值影响后不可能智能转换为 'Boolean',我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45836253/

10-16 08:30