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

86 views Asked by At

I pretty sure that the answer to the question in title is No. But i wrote a simple code and get a weird error when trying to compile. code:

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!!
}

the last line in code:

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

makes the compiler display the following error:

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

But, if i remove the following line the code is compiled:

hippo?.hunger = 5

Can someone explain me, what is wrong with this line of code that prevents the code from being compiled successfully?

enter image description here

1

There are 1 answers

8
cactustictacs On BEST ANSWER

It runs just fine as posted: Kotlin Playground example

That error usually comes up where you've checked something isn't null, so you can treat it as a non-null type (Int in this case), but that doesn't work for vars because they can change, and could be null again - so you need to use something like hippo?.hunger?.let { bla bla } where the value gets assigned to a temporary val (it by default) which can't be changed.

I'm not sure why you're getting the error there, maybe it's trying to use the println(message: Int) call instead of the println(message: Any?) call for some reason? You can put the cursor on println and do ctrl+Q (or your equivalent) to find out which function it thinks it's calling.

But yeah, if the smart casting is messing you around, it's probably a bug. Casting to Int? like you're doing is one way of doing it, or doing the let/run thing might work too (hippo?.hunger.run(::println)).

Is your main block closed by the way? The curly brace is missing