设置一个 var class 成员一个新值可以改变类型吗?

Does setting a var class member a new value can change is type?

我很确定标题问题的答案是否定的。 但是我写了一个简单的代码并在尝试编译时遇到了一个奇怪的错误。 代码:

open class Animal (val stttt:String, val str:String = "hjm") {
    open var fff: String = ""
    open var image = ""
    open val food = ""
    open val habitat = ""
    var hunger: Int? = 10
}

 class Hippo ( var strrr:Int = 7) : Animal("just") {
     override var image = "hippo.jpg"
     override var food = "grass"
     override val habitat = "water"
 }

fun main(args: Array<String>) {
    val hippo: Hippo? = Hippo()
    hippo?.hunger = 5
    println(hippo?.hunger)  // println(hippo?.hunger as Int?) works!!
}

最后一行代码:

println(hippo?.hunger) // println(hippo?.hunger as Int?) works!!

使编译器显示以下错误:

smart cast to Int is impossible, because hippo?.hunger is a mutable property that could have been changed by this time

但是,如果我删除以下行,代码将被编译:

hippo?.hunger = 5

谁能解释一下,这行代码有什么问题导致代码无法编译成功?

它运行得很好,正如发布的那样:Kotlin Playground example

该错误通常出现在您检查某些内容不为空的地方,因此您可以将其视为 non-null 类型(在本例中为 Int),但事实并非如此为 var 工作,因为它们可以更改,并且可能再次为 null - 所以你需要使用类似 hippo?.hunger?.let { bla bla } 的东西,其中值被分配给临时 valit默认情况下)无法更改。

我不确定你为什么会在那里收到错误,也许它出于某种原因试图使用 println(message: Int) 调用而不是 println(message: Any?) 调用?您可以将光标放在 println 上并执行 ctrl+Q (或等效的)以找出它认为正在调用的函数。

但是,是的,如果智能转换让您感到困惑,那可能是一个错误。像你正在做的那样转换为 Int? 是一种方法,或者做 let/run 也可能有效 (hippo?.hunger.run(::println))。

对了,你的主街区关门了吗?花括号不见了