我最近查看了一些kotlin代码,所有可为空的字段均初始化为null。
val x : String? = null
和val x : String?
有什么区别
我们应该将可为空的字段初始化为null吗?
答案 0 :(得分:4)
所有内容,甚至是可为空的变量和基元都需要在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。
答案 1 :(得分:3)
val x : String?
将根据定义的位置创建未初始化的变量或属性。如果它在类(而不是函数)中,则会创建一个属性,除非抽象,否则您无法创建未初始化的属性。例如,使用以下代码:
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),在这种情况下,覆盖类应对其进行初始化。
答案 2 :(得分:2)
必须初始化属性。因此,您必须进行初始化var x : String? = null
。不分配值只是属性的声明,因此您必须将其抽象为abstract val x : String?
。
或者,您也可以在非空类型上使用lateinit
。但这会产生影响,它不是空值,而是未初始化的lateinit var x : String
。