我们需要在 kotlin 中初始化可为空的字段吗?
Do we need to initialize nullable fields in kotlin?
最近复习了一些kotlin代码,所有可空字段都初始化为null。
val x : String? = null
和val x : String?
有什么区别
我们应该将可空字段初始化为空吗?
A 属性 必须初始化。因此你必须做初始化var x : String? = null
。不赋值只是 属性 的声明,因此你必须将其抽象化 abstract val x : String?
.
或者您可以使用 lateinit
,同样适用于不可为 null 的类型。但这有效果,它不是空的,而是未初始化的 lateinit var x : String
.
val x : String?
将创建一个未初始化的变量或 属性,具体取决于它的定义位置。如果它在 class(而不是函数)中,它会创建一个 属性,并且你不能创建一个未初始化的 属性,除非它是抽象的。例如,采用此代码:
class MyClass {
val x : String?
}
这不会编译。你会得到 Property must be initialized or be abstract
.
然而,此代码将编译
class MyClass {
fun test() {
val x : String?
}
}
但是这有点毫无意义,因为您将无法引用该变量:一旦您这样做,您就会得到 Variable 'x' must be initialized.
所以是的,通常在定义可为 null 的成员时,您应该初始化它(例如,使用 null 值),除非它是抽象的,在这种情况下,覆盖 class 应该初始化它。
一切,甚至是可为空的变量和基元,都需要在 Kotlin 中进行初始化。正如 tynn 所提到的,如果您需要覆盖,您可以将它们标记为抽象的。但是,如果您有接口,则不必初始化它们。这不会编译:
class Whatever {
private var x: String?
}
但这将:
interface IWhatever {
protected var x: String?
}
这也是:
abstract class Whatever {
protected abstract var x: String?
}
如果是在方法中声明的,则不必直接初始化,只要在访问前初始化即可。如果您熟悉的话,这与 Java 中的内容完全相同。
如果不在构造函数中初始化,需要使用lateinit
。或者,如果您有 val
,您可以覆盖 get
:
val something: String?
get() = "Some fallback. This doesn't need initialization because the getter is overridden, but if you use a different field here, you naturally need to initialize that"
正如我打开的那样,即使是可为空的变量也需要初始化。这就是 Kotlin 的设计方式,没有办法绕过它。所以是的,如果您不立即用其他东西初始化它,则需要将 String 显式初始化为 null。
最近复习了一些kotlin代码,所有可空字段都初始化为null。
val x : String? = null
和val x : String?
有什么区别
我们应该将可空字段初始化为空吗?
A 属性 必须初始化。因此你必须做初始化var x : String? = null
。不赋值只是 属性 的声明,因此你必须将其抽象化 abstract val x : String?
.
或者您可以使用 lateinit
,同样适用于不可为 null 的类型。但这有效果,它不是空的,而是未初始化的 lateinit var x : String
.
val x : String?
将创建一个未初始化的变量或 属性,具体取决于它的定义位置。如果它在 class(而不是函数)中,它会创建一个 属性,并且你不能创建一个未初始化的 属性,除非它是抽象的。例如,采用此代码:
class MyClass {
val x : String?
}
这不会编译。你会得到 Property must be initialized or be abstract
.
然而,此代码将编译
class MyClass {
fun test() {
val x : String?
}
}
但是这有点毫无意义,因为您将无法引用该变量:一旦您这样做,您就会得到 Variable 'x' must be initialized.
所以是的,通常在定义可为 null 的成员时,您应该初始化它(例如,使用 null 值),除非它是抽象的,在这种情况下,覆盖 class 应该初始化它。
一切,甚至是可为空的变量和基元,都需要在 Kotlin 中进行初始化。正如 tynn 所提到的,如果您需要覆盖,您可以将它们标记为抽象的。但是,如果您有接口,则不必初始化它们。这不会编译:
class Whatever {
private var x: String?
}
但这将:
interface IWhatever {
protected var x: String?
}
这也是:
abstract class Whatever {
protected abstract var x: String?
}
如果是在方法中声明的,则不必直接初始化,只要在访问前初始化即可。如果您熟悉的话,这与 Java 中的内容完全相同。
如果不在构造函数中初始化,需要使用lateinit
。或者,如果您有 val
,您可以覆盖 get
:
val something: String?
get() = "Some fallback. This doesn't need initialization because the getter is overridden, but if you use a different field here, you naturally need to initialize that"
正如我打开的那样,即使是可为空的变量也需要初始化。这就是 Kotlin 的设计方式,没有办法绕过它。所以是的,如果您不立即用其他东西初始化它,则需要将 String 显式初始化为 null。