Reputation: 66
Let's say I have a Kotlin class Dog
with two properties weight
and weightInKgs
class Dog(val weight: Double) {
// property without initializing works. Why?
val weightinKgs: Double
get() = weight/ 2.2;
}
The above code runs without errors. I know that every property in Kotlin must be initialized so why does defining a getter without initializing the property work? Secondly, when val
is changed to var
for weightInKgs
, it produces an error asking for initialization. How does changing it to var
break the code?
class Dog(val weight: Double) {
// well its doesn't work now.
var weightinKgs: Double
get() = weight/ 2.2;
}
Upvotes: 0
Views: 39
Reputation: 93551
Every property with a backing field must be initialized. A property has a backing field if any of the following is true:
=
.field
.field
.Otherwise, it does not have a backing field.
If there is no backing field used by the getter and/or setter, there is no need to initialize one. Your first code block has a custom getter that doesn't use field
.
In your second code block, you have a var
and it's using the implicit setter, which uses the backing field, so the backing field must be initialized.
Upvotes: 3
Reputation: 19524
If it's not obvious, get()
is a function that calculates a value (weight / 2.2
) every time you call it. It's basically the equivalent to this
fun getWeightInKgs(): Double {
return weight / 2.2
}
So that's why it doesn't have a backing field, it's not actually storing a value. But Kotlin presents these kinds of getX()
functions (and set
, is
etc) as properties, and encourages you to use property access syntax, so dog.weightInKgs
instead of dog.getWeightInKgs()
. Kinda hiding the specific implementation details
If you didn't want to calculate the weight every time, and just wanted to do it once, then you'd just do
val weightInKgs = weight / 2.2
and then it would have a backing field, because that value has to be stored somewhere. You could also have a getter function that refers to a private val
or var
and returns the value of that, instead of giving the property itself a backing field, but if you ever need to do that kind of thing you'll probably understand why you would! That's usually for when your getter and/or setter is doing something a bit more complicated than just hiding or validating an internal data value
Upvotes: 0