Как компилятор kotlin знает, должен ли val быть свойством или функцией
Следующий код котлинаval nameHash get() = name.hashCode()
может быть скомпилирован в java следующим образом
public final int getNameHash() {
return name.hashCode();
}
и свойство nameHash исчезает. Однако, когда val изменяется на var, компилятор говорит: «Свойство должно быть инициализировано». В чем более глубокая разница между var и val?
2 ответа
Как компилятор kotlin знает, должен ли val быть свойством или функцией
Что касается языка Kotlin , то обозначает свойства, а не функции. Однако между этими двумя объявлениями свойств есть разница:
val nameHash get() = name.hashCode()
var nameHash get() = name.hashCode()
И это то, что первое свойство не имеет резервного поля . Свойства с резервными полями должны быть так или иначе инициализированы, например:
var nameHash = 0 // for example
get() = name.hashCode()
И именно поэтому ваш код сvar
не скомпилировал.
Если вы спрашиваете о ситуациях, когда резервное поле создается для свойства Kotlin, они перечислены в спецификации:
Однако резервное поле создается для свойства только в следующих случаях.
- У свойства нет пользовательских методов доступа;
- У свойства есть метод доступа по умолчанию;
- Свойство имеет настраиваемый метод доступа и использует
field
свойство;- Изменяемое свойство имеет настраиваемый геттер или сеттер, но не оба.
Это те случаи, когда вашему объекту требуется резервное поле. Твойvar nameHash
удовлетворяет этому последнему случаю, потому что это «изменяемое свойство». Если вы используетеval
вместо этого оно больше не является изменяемым свойством и не удовлетворяет ни одному из этих случаев.
Интуитивно понятно, что изменяемое свойство без установщика нуждается в резервном поле, потому что нужно иметь возможность устанавливать свойство. Как вы можете установить его, если у него нет сеттера? Что ж, компилятор Kotlin решает проблему, генерируя резервное поле и вместо этого просто устанавливая резервное поле.
Свойство представляет собой функции & . Свойства только для чтения реализуют только функцию, но, тем не менее, это функция, поэтому все, что написано в свойстве, будет выполняться каждый раз при его вызове.
В Котлине ключевые слова:val
совпадает со свойством только для чтения, то есть требуется только для реализации функции. Когда вы положилиvar
ключевое слово, компилятор ожидает, что вы реализуете обаget()
& функции.
Итак, ошибка компиляции, потому что ваше свойство отсутствуетset()
функция, которая обычно нужна для хранения значения (или, как говорит компилятор: должна быть инициализирована).