How does kotlin compiler know whether a val should be a property or a function
As far as the Kotlin language is concerned, val
denotes properties, never functions. However, there is a difference between these two property declarations:
val nameHash get() = name.hashCode()
var nameHash get() = name.hashCode()
And that is that the first property does not have a backing field. Properties with backing fields must be initialised one way or another, for example:
var nameHash = 0 // for example
get() = name.hashCode()
And this is why your code with var
didn't compile.
If you are asking for the situations when a backing field is generated for a Kotlin property, they are listed in the spec:
However, the backing field is created for a property only in the
following cases
- A property has no custom accessors;
- A property has a default accessor;
- A property has a custom accessor, and it uses
field
property;
- A mutable property has a custom getter or setter, but not both.
These are the cases where your property needs a backing field. Your var nameHash
satisfies that last case, because it is a "mutable property". If you use val
instead, it is not a mutable property anymore and doesn't satisfy any of those cases.
Intuitively, a mutable property without setter needs a backing field because one must need to be able to set the property. How can you set it when it has no setter? Well, the Kotlin compiler solves the problem by generating a backing field and just sets the backing field instead.