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

时间:2017-12-05 23:47:14

标签: kotlin lazy-initialization kotlin-delegate

我需要一个需要在通话时初始化的矩形。

这是我的代码;

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'必须初始化   变量&text;文本高度'必须初始化

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

我做错了什么?

1 个答案:

答案 0 :(得分:3)

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

更新: - 为什么初始化顺序很重要?

我们可以将此行为称为Kotlin的Null-Safty。当我们更改 init block 变量声明的顺序时,我们违反了此规则。

  

来自Kotlin官方文件: -

     

Kotlin的类型系统旨在消除NullPointerException的问题。   我们的代码。 NPE的唯一可能原因可能是

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

  2.   
  3. 使用!!下面描述的运算符;

  4.   
  5. 外部Java代码导致了它;

  6.   
  7. 在初始化方面存在一些数据不一致(构造函数中可用的未初始化在某处使用)。

  8.   

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