如何在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你使用的是懒惰初始化器,但是编译器不知道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) }
更新: – 为什么初始化问题的顺序在这里?
我们可以把这种行为称为Kotlin的Null-Safty 。 当我们改变init块和variables声明的顺序时,我们打破了这个规则。
从Kotlin官方文件: –
Kotlin的types系统旨在消除我们的代码中的NullPointerException。 NPE的唯一可能的原因可能是
显式调用抛出NullPointerException();
!!的用法! 如下所述的运营商;
外部的Java代码造成了它;
在初始化方面有一些数据不一致的地方(在某个地方使用了一个未初始化的构造函数)。
除了这四个条件,它总是确保在编译时初始化一个variables。 与我们的情况一样,只是确保使用的variables在使用之前必须被初始化。