Чем val отличается от var
val— значение присваивается один раз, изменить его нельзя;var— значение можно менять сколько угодно.
fun main() {
val city = "Minsk"
var visits = 1
visits = visits + 1
println("$city: $visits")
}Minsk: 2Строка city = "Brest" в этой программе не соберётся: компилятор ответит, что val нельзя присвоить заново (val cannot be reassigned). Исправление — либо объявить переменную через var, либо, что чаще правильнее, завести новую: val newCity = "Brest".
Что выбирать
По умолчанию — val. var — только если значение действительно меняется: счётчик, сумма в цикле, текущее состояние игры. Чем меньше var, тем проще читать программу: про val сразу известно, что дальше он тот же. IntelliJ IDEA сама подсказывает, если var нигде не меняется, и предлагает заменить его на val.
Тип у обоих задаётся один раз: в var visits = 1 можно положить другое число, но не строку.
val не значит «содержимое не меняется»
val запрещает положить в переменную другой объект, но не менять сам объект:
fun main() {
val items = mutableListOf("bread")
items.add("milk")
println(items)
}[bread, milk]Это работает: список тот же, изменилось его содержимое. А items = mutableListOf() уже не соберётся. Чтобы содержимое тоже было неизменным, берите список только для чтения — listOf(...).
val и const val
val | const val | |
|---|---|---|
| Где объявляется | где угодно | вне функций, в object или companion object |
| Значение | любое, можно посчитать при запуске | известно при сборке программы: число, строка, true/false |
| Пример | val now = System.currentTimeMillis() | const val MAX_USERS = 100 |
const val — настоящая константа: компилятор подставляет её значение прямо в код. Для неё значение должно быть записано в программе или посчитано из других констант.
Отложенное присваивание
Объявить val и присвоить позже можно, но только один раз и до первого использования:
fun main() {
val n = 7
val parity: String
if (n % 2 == 0) {
parity = "even"
} else {
parity = "odd"
}
println(parity)
}oddКомпилятор проверяет, что значение присвоено ровно один раз на любом пути программы. Короче то же самое пишется через if-выражение: val parity = if (n % 2 == 0) "even" else "odd".
Для свойств класса, которые получают значение не в конструкторе, а позже, есть lateinit var — о нём в справке lateinit — отложенная инициализация.
Сравнение с Java
val в Kotlin — это final переменная в Java, а var — обычная. Разница в том, что в Kotlin val пишется так же коротко, как var, поэтому неизменяемые переменные становятся привычкой.