Why this works: ``` class Foo { private val te...
# announcements
m
Why this works:
Copy code
class Foo {
    private val test: String
    init {
        test = "test"
    }
}
and this doesn’t:
Copy code
class Foo {
    private val test: String
    init {
        bar()
    }
    private fun bar() {
        test = "test"
    }
}
Is there any valid case why it may fail? Or it’s the compiler’s fault that it doesn’t recognize
bar
is called inside an
init
?
r
The compiler has to make sure all properties are initialized after object creation. You're allowed to defer initialization to an
init
block because the compiler can statically check that, but it won't check function calls you do from
init
blocks, because these could become arbitrarily complex and would probably slow down the compiler significantly.
m
Hm it doesn’t work even if I make the function
inline
. I would expect it to work in this case because it would be essentially the same as having this code inside a constructor, right?
r
Well, the compiler works on the AST and not the compiled bytecode, and it probably simply doesn't check function calls, no matter if they are inlined or not. Even inlined function calls might be quite complex. It's just a tradeoff decision made.
Why do you need this functionality so badly?
m
I don’t, I can make 2
init
blocks. But I’m just curious what is the reason it doesn’t work. I know why calling methods from within a constructor can be bad so I expected to be a specific reason for this in Kotlin.
p
Anyway compiler will not allow assignment to variable
test
inside method as variable is declared as
val
.
r
@Pavlo Liapota True, but the same case might arise with a
var
.
p
Then
lateinit
can be used 🙂 Not a clean solution, but as you said “It’s just a tradeoff decision made.” May be
contract
will be added for this case in the future ¯\_(ツ)_/¯
r
"Not clean" seems a little like an understatement, I'd say that approach undermines much of what the language is trying to accomplish 😄
p
Yes, but would you agree that if you need to initialize your property inside method, then probably there is a problem in the design of such class? 🙂
r
Yup, that's the gist of it