Today I learned this is valid. Does anyone have in...
# getting-started
j
Today I learned this is valid. Does anyone have insight into why this is? To me, it seems extremely wrong and confusing to be able to assign a
val
at all somewhere other that its declaration site.
Copy code
class Test {
    private val test: String
    
    init {
        test = "Hello"
    }
}
c
The primary constructor initializes a class instance and its properties in the class header. The class header can’t contain any runnable code. If you want to run some code during object creation, use initializer blocks inside the class body. Initializer blocks are declared with the
init
keyword followed by curly braces. Write any code that you want to run within the curly braces.
https://kotlinlang.org/docs/classes.html#constructors
j
This is valid because the initializer blocks is always executed first before properties can be accessed. When you perform the inline declaration, I believe the compiler is effectively moving the assignment to the top of initializer blocks (the inline is syntactic sugar). It is illegal to try to set
test
again in the initializer block.
☝🏻 1
👏 1
Copy code
class Test {
    private val test: String

    init {
        test = "Hello"
        test = "Hello, again"
    }
}
This is a compiler error
l
And if you don't set it at all, it's also a compiler error.
n
And local
val
variables can also be be initialized subsequently. Example:
Copy code
fun sample(cond: Boolean) {
    val f: Int
    if (cond) {
        f = 3
    } else {
        f = 6
    }
    println(f / 2)
}
The compiler also here enforces that
f
is always initialized before used. This sometimes is helpful if the code to initialize a
val
variable is complicated or if you want to set multiple
val
based on the same condition.