我应该在声明、init块、构造函数或lateinit上初始化变量吗



我想知道在kotlin中初始化变量(据我所知(的4种方法与最容易接受的方法之间有什么区别。

首先,在声明时初始化它:

class MyClass {
var textString: String = "Hello world"
}

第二,在init块上初始化它:

class MyClass {
var textString: String
init {
textString = "Hello world"
}
}

第三,使用构造函数:

class MyClass {
var textString : String
constructor() {
this.textString = "Hello world"
}
}

第四,后期:

class MyClass {
lateinit var textString : String
fun initializeVariable() { //Assume this is called by something
this.textString = "Hello world"
}
}

我主要是在寻找编译时间和整体";良好实践";。我知道一些";技巧";你可以使用,比如使用init块来初始化一些变量,这些变量总是相同的,无论使用什么构造函数,但这是合适的方法吗?

从技术角度来看,没有太大区别,至少在像示例中这样的简单属性方面没有太大差异-属性无论如何都会初始化。

lateinit修饰符在这里是一个小例外——它允许延迟初始化:这就像说";我现在不能设置一个有意义的值,但我确信它会在第一次使用之前设置"。它在Kotlin-Spring框架集成中很有用,因为某种原因,它不想/不能使用构造函数注入,并允许属性注入。

@Autowired lateinit var foo: Foo

或者当使用Spring的@Value注释时

@Value("#{props.foo}") lateinit var foo: String

不过,从读者/维护者的角度来看,这是有区别的,当你需要一些额外的功能时,比如先决条件验证。根据经验,尽早初始化属性:首选方式是在主构造函数中:

class Foo(var bar: String = "default value")

你的代码的读者,也许是未来的你,不必跳过代码来理解";默认值";来自-它就在构造函数中!

此外,客户端代码可以在构建对象时轻松更改值,或者将其保留为默认

// set new value
val foo: Foo = Foo(bar = "specific value other than default")
// leave the default
val defaultFoo: Foo = Foo()

在类主体中初始化属性后,强制客户端代码首先创建一个具有默认值的实例,然后再重写。

val foo = Foo()
foo.bar = "not so default"

此外,如果有一些先决条件需要检查,那么在主构造函数中设置值时更容易做到这一点。例如,foo String属性不能为空:

class Foo(var bar: String = "default") {
init {
require(bar.isNotBlank()) { "Bar cannot be blank" }
}
}

在可能的情况下,我会使用构造函数初始化。

此外,如果你愿意花几美元买一本关于Kotlin良好实践和模式的书,我强烈推荐Marin Moskała的《有效的Kotlin》https://leanpub.com/effectivekotlin

lateinit不相关,因为它不会初始化任何内容。

同一行上的初始化仅适用于简单的属性。您可以使用闭包,然后调用它们,就像val i = { // complex code }()一样,但这很难看。

有关构造函数与init块的详细讨论,请参阅。理解初始化顺序的最简单方法是创建一个具有主块、辅助块和init块的类,然后使用println或只是调试器来跟踪执行。

最新更新