如何以优雅的方式在Kotlin中使用init构造

时间:2018-03-15 12:37:06

标签: oop syntax kotlin

在类构建过程中有很多examples如何使用init,但它们大多没有使用实际的类属性。

我需要做的是在对象init上从数据库初始化一个类属性。到目前为止,我有这个:

class MyObj constructor(val id: Long){

   var data: MutableMap? = null

   init {
       data = db.find(id) // more like pseudocode, db fetch is done and result assigned to data property
   }
}

但对我来说似乎有点过于复杂。有没有更好,更优雅的方法呢?

2 个答案:

答案 0 :(得分:3)

您可以直接在类体中初始化属性:

class MyObj(val id: Long) {
     val data: MutableMap = db.find(id)
}

然后您不需要将其声明为可空类型,并且可以使用val代替var。 (我还删除了多余的constructor关键字。)。

答案 1 :(得分:2)

你可以写:

class MyObj constructor(val id: Long){
    val data: Map<String, String> = mapOf()
}

相当于:

class MyObj constructor(val id: Long){
    val data: Map<String, String>
    init {
        data = mapOf()
    }
}
如果你需要为对象初始化引入一些逻辑,比如错误检查等,

初始化块非常有用。或者你可以使用或不使用init块来实现。但请记住更具可读性的内容:

class MyObj constructor(val id: Long){
    val data: Map<String, String> = if (id == 0L) {
        mapOf(Pair("", ""))
    } else {
        throw IllegalStateException()
    }
} // without init

class MyObj constructor(val id: Long){
    val data: Map<String, String>

    init {
        data = if (id == 0L) {
            mapOf(Pair("", ""))
        } else {
            throw IllegalStateException()
        }
    }
} // with init

你也可以使用lazy初始化这个值(这意味着属性将被初始化为函数,但是当你第一次请求它时,将分配值,而不是在创建对象时)。我想从db获取值可能会很长,所以它可能很有用:

val data: Map<String, String> by lazy { mapOf() }