Подтвердить что ты не робот

Почему Котлин не позволяет использовать lateinit с примитивными типами?

В языке Kotlin мы по умолчанию должны инициализировать каждую переменную при ее вводе. Чтобы этого избежать, можно использовать ключевое слово lateinit. Ссылаясь на переменную lateinit до того, как она была инициализирована, вы получите исключение во время выполнения.

lateinit не может, однако, использоваться с примитивными типами. Почему это так?

4b9b3361

Ответ 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.

Поправьте меня, если это не так.