Как реализовать ленивое свойство в Котлине, которое требует другого имущества?

Мне нужен прямоугольник, который нужно инициализировать при вызове.

Вот мой код;

class EpheButton private constructor( private val text: String, private val x: Float, private val y: Float, private val projectionMatrix: Matrix4) : Disposable { private val spriteBatch: SpriteBatch = SpriteBatch() private val bitmapFont: BitmapFont = BitmapFont() private val shapeRenderer: ShapeRenderer = ShapeRenderer() private val textWidth: Float private val textHeight: Float private val rectangle :Rectangle by lazy { Rectangle(x, y, textWidth, textHeight) } init { bitmapFont.data.setScale(2f) bitmapFont.region.texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) bitmapFont.color = Color.BLUE val layout = GlyphLayout() layout.setText(bitmapFont, text) textWidth = layout.width textHeight = layout.height } 

Я получаю ошибки для private val rectangle :Rectangle by lazy { Rectangle(x, y, textWidth, textHeight) } который говорит, что;

Переменная «textWidth» должна быть инициализирована. Переменная «textHeight» должна быть инициализирована

Но я уже инициализирую их в блоке кода init{} .

Что я делаю не так?

В kotlin вам нужно инициализировать переменную перед ее использованием. Вы используете ленивый инициализатор для Rectangle, но компилятор не знает статус textWidth и textHeight

Класс выглядит так

 class EpheButton private constructor( private val text: String, private val x: Float, private val y: Float, private val projectionMatrix: Matrix4) : Disposable { private val spriteBatch: SpriteBatch = SpriteBatch() private val bitmapFont: BitmapFont = BitmapFont() private val shapeRenderer: ShapeRenderer = ShapeRenderer() private val textWidth: Float private val textHeight: Float init { bitmapFont.data.setScale(2f) bitmapFont.region.texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) bitmapFont.color = Color.BLUE val layout = GlyphLayout() layout.setText(bitmapFont, text) textWidth = layout.width textHeight = layout.height } private val rectangle :Rectangle by lazy { Rectangle(x, y, textWidth, textHeight) } 

Обновлено: – Зачем здесь порядок инициализации?

Мы можем назвать это поведенческое поведение Null-Safty of Kotlin. Когда мы изменяем порядок блока init и объявления переменных , мы нарушаем это правило.

Из официального документа Котлина: –

Система типа Kotlin предназначена для устранения NullPointerException из нашего кода. Единственными возможными причинами NPE могут быть

  1. Явный вызов бросить NullPointerException ();

  2. Использование !! оператор, описанный ниже;

  3. Внешний код Java вызвал это;

  4. Существует некоторая несогласованность данных в отношении инициализации (где-то используется неинициализированное это доступное в конструкторе).

Помимо этих четырех условий, он всегда гарантирует, что переменная инициализируется во время компиляции. так же, как и в нашем случае, это просто гарантирует, что используемая переменная должна быть инициализирована до ее использования.

Intereting Posts
Как файл kotlin работает на Android-версии 3.0 Canary 4? Возможно ли иметь расширения функций на лямбдах? Потоки, выполняемые последовательно Kotlin, приемник функции кастинга Как переписать этот класс Java в класс данных Kotlin? Как получить данные из пользовательской таблицы в Corda Установите адаптер ViewPager через привязку данных Как правильно реализовать lateinit с пользовательскими объектами класса для использования в onCreate () в android, избегая ошибки Property getter или setter expected Пункт Onclick RecyclerView Kotllin Android Создайте приложение для Android, написанное в Kotlin, используя систему Buck build Почему Котлин не разрешает использовать какой-либо код в основном конструкторе? ProGuard заставляет Gson возвращать LinkedTreeMap вместо моего типа Обнаруживать конфликты просмотров и предотвращать перенасыщение Пытается создать простой recyclerView в Kotlin, но адаптер не применяется должным образом Как начать аннотация Обработка (kapt) для локальной библиотеки?