如何在 Kotlin 中实现一个需要另一个 属性 的惰性 属性?
How to implement a lazy property in Kotlin that requires another property?
我需要一个需要在调用时初始化的矩形。
这是我的代码;
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) }
行的错误,上面写着;
Variable 'textWidth' must be initialized
Variable 'textHeight' must be initialized
但我已经在 init{}
代码块上初始化它们了。
我做错了什么?
在 kotlin 中,您必须在使用变量之前对其进行初始化,您正在为 Rectangle 使用延迟初始化程序,但编译器不知道 textWidth 和 [=23 的状态=]文字高度
所以 class 看起来像这样
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 和 variable declaration 的顺序时,我们就打破了这条规则。
From Kotlin official documentaion :-
Kotlin's type system is aimed to eliminate NullPointerException's from
our code. The only possible causes of NPE's may be
An explicit call to throw NullPointerException();
Usage of the !! operator that is described below;
External Java code has caused it;
There's some data inconsistency with regard to initialization (an uninitialized this available in a constructor is used somewhere).
除这四个条件外,它始终确保在编译时初始化变量。与我们的情况一样,它只是确保使用的变量必须在使用之前进行初始化。
我需要一个需要在调用时初始化的矩形。
这是我的代码;
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) }
行的错误,上面写着;
Variable 'textWidth' must be initialized Variable 'textHeight' must be initialized
但我已经在 init{}
代码块上初始化它们了。
我做错了什么?
在 kotlin 中,您必须在使用变量之前对其进行初始化,您正在为 Rectangle 使用延迟初始化程序,但编译器不知道 textWidth 和 [=23 的状态=]文字高度
所以 class 看起来像这样
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 和 variable declaration 的顺序时,我们就打破了这条规则。
From Kotlin official documentaion :-
Kotlin's type system is aimed to eliminate NullPointerException's from our code. The only possible causes of NPE's may be
An explicit call to throw NullPointerException();
Usage of the !! operator that is described below;
External Java code has caused it;
There's some data inconsistency with regard to initialization (an uninitialized this available in a constructor is used somewhere).
除这四个条件外,它始终确保在编译时初始化变量。与我们的情况一样,它只是确保使用的变量必须在使用之前进行初始化。