【发布时间】:2016-08-04 07:40:42
【问题描述】:
在 Kotlin 语言中,默认情况下,我们必须在引入每个变量时对其进行初始化。为避免这种情况,可以使用lateinit 关键字。在初始化之前引用lateinit 变量会导致运行时异常。
lateinit 但是不能与原始类型一起使用。为什么会这样?
【问题讨论】:
标签: initialization kotlin primitive
在 Kotlin 语言中,默认情况下,我们必须在引入每个变量时对其进行初始化。为避免这种情况,可以使用lateinit 关键字。在初始化之前引用lateinit 变量会导致运行时异常。
lateinit 但是不能与原始类型一起使用。为什么会这样?
【问题讨论】:
标签: initialization kotlin primitive
对于(不可为空的)对象类型,Kotlin 使用 null 值来标记 lateinit 属性尚未初始化,并在访问该属性时引发相应的异常。
对于原始类型,没有这样的值,因此无法将属性标记为未初始化并提供lateinit 需要提供的诊断。 (我们可以尝试使用某种单独的标记,但在通过反射初始化字段时该标记不会更新,这是lateinit 的主要用例)。
因此,lateinit 仅支持对象类型的属性。
【讨论】:
lateinit Int 不能在运行时用 Integer 类型表示,它能够在尚未初始化时保持 null 值?
lateinit var int: Int? 那么我不明白为什么这不起作用,因为 Kotlin 已经用 Integer 代表 Int? ...
lateinit 和? 有冲突。前者说你有一个变量在初始化后总是有一些值,后者说你有一个变量可能有也可能没有一些值。您不需要?. 或检查lateinit var 的无效性。
简短的回答是,对于原语,您始终可以使用 0 作为默认值,并使用可空类型 null 作为默认值。只有不可为空的非原始类型可能需要lateinit 才能绕过类型安全系统。
其实在 Kotlin 中没有必要初始化一个变量,只要它在第一次访问之前有值,并且可以静态地证明。这意味着这段代码完全有效:
fun main(args: Array<String>) {
var x: Int
val y: Double
x = 0
y = x + 0.1
println("$x, $y")
}
但是有(罕见的)初始化无法静态证明的情况。最常见的情况是使用任何形式的依赖注入的类字段:
class Window {
@Inject lateinit parent: Parent
}
【讨论】:
我认为,在原语的情况下,简单地初始化它以让我说 0 并将简单值保存在内存中而不是存储关于由 lateinit 机制使用的对象可空性的额外信息所花费的资源更少。
如果不是这样,请纠正我。
【讨论】: