¿Cómo implementar una propiedad floja en Kotlin que requiere otra propiedad?

Necesito un rectángulo que debe inicializarse en el momento de la llamada.

Aquí está mi código;

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 } 

Obtengo errores para el private val rectangle :Rectangle by lazy { Rectangle(x, y, textWidth, textHeight) } de la línea private val rectangle :Rectangle by lazy { Rectangle(x, y, textWidth, textHeight) } que dice eso;

La variable 'textWidth' debe inicializarse La variable 'textHeight' debe estar inicializada

Pero ya los estoy inicializando en el bloque de código init{} .

¿Qué estoy haciendo mal?

En kotlin, debe inicializar una variable antes de usarla, está usando un inicializador lento para Rectángulo pero el comstackdor no conoce el estado de textWidth y textWeight

Entonces la class se ve así

 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) } 

Actualizado: – ¿Por qué el order de la initialization está aquí?

Podemos llamar a este comportamiento weinetworking Null-Safty de Kotlin. Cuando cambiamos el order del bloque de inicio y la statement de variable , estamos rompiendo esta regla.

De la documentacion oficial de Kotlin:

El sistema de types de Kotlin tiene como objective eliminar NullPointerException de nuestro código. Las únicas causas posibles de NPE pueden ser

  1. Una llamada explícita para lanzar NullPointerException ();

  2. Uso de la !! operador que se describe a continuación;

  3. El código Java externo lo ha causado;

  4. Hay cierta inconsistencia de datos con respecto a la initialization (una no inicializada disponible en un constructor se usa en alguna parte).

Aparte de estas cuatro condiciones, siempre asegura que una variable se inicializa en el momento de la compilation. lo mismo con nuestro caso, solo asegurando que la variable utilizada debe inicializarse antes de usarse.