如何在Kotlin中实现一个需要另一个属性的懒惰属性?

我需要一个矩形,需要在通话中初始化。

这是我的代码;

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) }错误private val rectangle :Rectangle by lazy { Rectangle(x, y, textWidth, textHeight) }这说,

variables“textWidth”必须被初始化variables“textHeight”必须被初始化

但是我已经在init{}代码块上初始化它们了。

我究竟做错了什么?

在kotlin中,你必须在使用它之前初始化一个variables,对于Rectangle你使用的是懒惰初始化器,但是编译器不知道textWidthtextHeight的状态

所以类看起来像这样

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

更新: – 为什么初始化问题的顺序在这里?

我们可以把这种行为称为Kotlin的Null-Safty 。 当我们改变init块variables声明的顺序时,我们打破了这个规则。

从Kotlin官方文件: –

Kotlin的types系统旨在消除我们的代码中的NullPointerException。 NPE的唯一可能的原因可能是

  1. 显式调用抛出NullPointerException();

  2. !!的用法! 如下所述的运营商;

  3. 外部的Java代码造成了它;

  4. 在初始化方面有一些数据不一致的地方(在某个地方使用了一个未初始化的构造函数)。

除了这四个条件,它总是确保在编译时初始化一个variables。 与我们的情况一样,只是确保使用的variables在使用之前必须被初始化。