How come one of these functions works, and the oth...
# getting-started
j
How come one of these functions works, and the other not?
Copy code
data class A(val x: String = "default") {
    fun toObjectNotWorking(): Any {
        return object {
            // Type checking has run into a recursive problem
            val x = x
        }
    } 
    
    fun toObjectWorking(): Any {
        val x2 = x
        return object {
            val x = x2
        }
    }
}
If I define a type on the value in the object in
toObjectNotWorking
I get
Variable x must be initalized
. Is there some other syntax to refer to the `x`field defined in
A
?
e
Copy code
this@A.x
❤️ 1
j
Makes sense when you think about it. Haven't experimented that much with object declarations. Thanks. 🙏
c
Oh, that's very interesting. To my knowledge, this is the only place in the Kotlin language where you can assign a variable to itself? If you specify types explicitly,
Copy code
return object {
    val x: String = x
}
you get the error
Variable 'x' must be initialized
, so the compiler does notice that this is unsafe. @Jonathan Olsson to avoid such surprises in the future, if you put your cursor on one variable, IntelliJ will highlight all other usages of the same variable (and not other variables that have the same name), so it becomes easy to notice that this is trying to assign
x
to itself and not using the
x
from
A
.
e
you can't assign a variable to itself, but the inner class's
val x
shadows the outer class's
val x
so that's what
x
means there
that's different from
Copy code
class A(x: String) {
    val x: String = x
which is legal because the right-hand
x
refers to the constructor parameter, not
this.x
https://kotlinlang.org/spec/scopes-and-identifiers.html#linked-scopes covers the rules in detail, but in short: names that can't be
this
- or
this@
-qualified (e.g. parameters, local variables) take precedence over names that can be qualified, and then all
this
-qualified names follow nesting and inheritance
✔️ 1