Почему Котлин не позволяет использовать lateinit с примитивными типами?
В языке Kotlin мы по умолчанию должны инициализировать каждую переменную при ее вводе. Чтобы этого избежать, можно использовать ключевое слово lateinit
. Ссылаясь на переменную lateinit
до того, как она была инициализирована, вы получите исключение во время выполнения.
lateinit
не может, однако, использоваться с примитивными типами. Почему это так?
Ответы
Ответ 1
Для типов объектов Kotlin использует значение null
, чтобы отметить, что свойство lateinit
не было инициализировано и выбрасывать соответствующее исключение при доступе к свойству.
Для примитивных типов такого значения нет, поэтому нет возможности пометить свойство как неинициализированное и предоставить диагностику, которую должен предоставить lateinit
. (Мы могли бы попытаться использовать какой-то отдельный маркер, но этот маркер не обновлялся при инициализации поля через отражение, что является основным прецедентом lateinit
).
Следовательно, lateinit
поддерживается только для свойств типов объектов.
Ответ 2
Короткий ответ заключается в том, что с примитивами вы всегда можете использовать 0
как значение по умолчанию и с нулевыми типами null
по умолчанию. Для нестандартных типов непустых типов может понадобиться lateinit
для работы с системой безопасности типа.
На самом деле нет необходимости инициализировать переменную в Kotlin, если она имеет значение до первого доступа и может быть статически доказано. Это означает, что этот код абсолютно корректен:
fun main(args: Array<String>) {
var x: Int
val y: Double
x = 0
y = x + 0.1
println("$x, $y")
}
Но есть (редкие) случаи, когда инициализация не может быть статически доказана. Наиболее распространенным случаем является поле класса, которое использует любую форму инъекции зависимостей:
class Window {
@Inject lateinit parent: Parent
}
Ответ 3
Я думаю, что в случае примитивов требуется меньше ресурсов, чтобы просто инициализировать его, чтобы позволить мне сказать 0 и удерживать простое значение в памяти, а не хранить дополнительную информацию об обнуляемости объекта, которая используется механизмом lateinit.
Поправьте меня, если это не так.