Home > Blockchain >  How does kotlin compiler know whether a val should be a property or a function
How does kotlin compiler know whether a val should be a property or a function

Time:07-03

The following kotlin code val nameHash get() = name.hashCode() can be compiled into java as follows

public final int getNameHash() {
    return name.hashCode();
}

and the property nameHash disapears. However when the val is changed to var, the compiler says "Property must be initialized" What is the deeper difference between var and val?

CodePudding user response:

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.

CodePudding user response:

Property is a functions set() & get(). Read-only properties implement only the get() function, but still, it's a function, so everything written in the property will be executed every time it's called.

In Kotlin, keywords: val is the same as the read-only property, meaning it's required to implement only get() function. When you put var keyword, compiler expects you to implement both get() & set() functions.

So, compile error there because your property missing set() function that is usually needed to store a value (or as the compiler says: must be initialized).

CodePudding user response:

The error message is a little confusing in this case. The difference between val and var is that val means there is a getter while var means there is a getter and a setter. To fix your code you need to add an implementation for the setter:

var nameHash
    get() = name.hashCode()
    set(hash: Int) { ... }

Although, in this case I don't think it makes too much sense. We can't set the hash code value of the name.

  • Related