为什么 Kotlin 不允许对原始类型使用 lateinit?
Why doesn't Kotlin allow to use lateinit with primitive types?
在Kotlin语言中,默认情况下,我们必须在引入每个变量时对其进行初始化。为避免这种情况,可以使用 lateinit
关键字。在初始化之前引用 lateinit
变量会导致运行时异常。
但是,lateinit
不能与原始类型一起使用。为什么会这样?
一个简短的回答是,对于原语,您始终可以使用 0
作为默认值,而使用可空类型 null
作为默认值。只有不可为 null 的非基本类型可能需要 lateinit
才能绕过类型安全系统。
实际上,在 Kotlin 中不需要初始化一个变量,只要它在第一次访问之前有一个值并且可以静态证明。这意味着此代码完全有效:
fun main(args: Array<String>) {
var x: Int
val y: Double
x = 0
y = x + 0.1
println("$x, $y")
}
但是在某些情况下(很少)无法静态证明初始化。最常见的情况是 class 字段,它使用任何形式的依赖注入:
class Window {
@Inject lateinit parent: Parent
}
对于(不可为空的)对象类型,Kotlin 使用 null
值来标记 lateinit
属性 尚未初始化,并在 属性 被访问。
对于原始类型,没有这样的值,因此无法将 属性 标记为未初始化并提供 lateinit
需要提供的诊断。 (我们可以尝试使用某种单独的标记,但在通过反射初始化字段时不会更新该标记,这是 lateinit
的主要用例)。
因此,lateinit
仅支持对象类型的属性。
我认为对于基元来说,简单地初始化它让我说 0 并将简单值保存在内存中而不是存储有关 lateinit 机制使用的对象可空性的额外信息所占用的资源更少。
如果不是这样请纠正我。
在Kotlin语言中,默认情况下,我们必须在引入每个变量时对其进行初始化。为避免这种情况,可以使用 lateinit
关键字。在初始化之前引用 lateinit
变量会导致运行时异常。
lateinit
不能与原始类型一起使用。为什么会这样?
一个简短的回答是,对于原语,您始终可以使用 0
作为默认值,而使用可空类型 null
作为默认值。只有不可为 null 的非基本类型可能需要 lateinit
才能绕过类型安全系统。
实际上,在 Kotlin 中不需要初始化一个变量,只要它在第一次访问之前有一个值并且可以静态证明。这意味着此代码完全有效:
fun main(args: Array<String>) {
var x: Int
val y: Double
x = 0
y = x + 0.1
println("$x, $y")
}
但是在某些情况下(很少)无法静态证明初始化。最常见的情况是 class 字段,它使用任何形式的依赖注入:
class Window {
@Inject lateinit parent: Parent
}
对于(不可为空的)对象类型,Kotlin 使用 null
值来标记 lateinit
属性 尚未初始化,并在 属性 被访问。
对于原始类型,没有这样的值,因此无法将 属性 标记为未初始化并提供 lateinit
需要提供的诊断。 (我们可以尝试使用某种单独的标记,但在通过反射初始化字段时不会更新该标记,这是 lateinit
的主要用例)。
因此,lateinit
仅支持对象类型的属性。
我认为对于基元来说,简单地初始化它让我说 0 并将简单值保存在内存中而不是存储有关 lateinit 机制使用的对象可空性的额外信息所占用的资源更少。
如果不是这样请纠正我。