Kotlin数据类便捷构造函数

时间:2018-07-26 16:03:48

标签: constructor kotlin data-class

我在Kotlin上还很陌生,我一直坚持制作类似于此Swift结构的数据类:

struct AppVersion {
    let major: Int
    let minor: Int
    let patch: Int
}

extension AppVersion {
    init(version: String) {
        let parts = version.split(separator: ".")
        let numbers = parts.map { Int($0) ?? 0 }
        self.init(major: numbers[0], minor: numbers[1], patch: numbers[2])
    }
}

为清楚起见,我们仅假设toInt()不抛出,并且版本字符串中始终有3个组件。

我有两种可行的解决方案。使用伴随对象:

data class AppVersion (val major: Int, val minor: Int, val patch: Int) {
    companion object {
        fun fromString(version: String): AppVersion {
            val parts = version.split(".").map { it.toInt() }
            return AppVersion(parts[0], parts[1], parts[2])
        }
    }
}

或者写一些看起来很糟糕的东西:

data class AppVersion (val major: Int, val minor: Int, val patch: Int) {
    constructor(version: String) : this(
            version.split(".")[0].toInt(), 
            version.split(".")[1].toInt(), 
            version.split(".")[2].toInt()
    )
}

但是为便利构造函数使用更长的方法名称似乎很奇怪,第二个选择也很糟糕。

是否可能这样?

data class AppVersion (val major: Int, val minor: Int, val patch: Int) {
    constructor(version: String): this(0, 0, 0) {
        val parts = version.split(".").map { it.toInt() }
        this(parts[0], parts[1], parts[2])
    }
}

1 个答案:

答案 0 :(得分:1)

超级构造函数调用必须是构造函数的第一条语句,并且只能出现一次。另外,每个val必须初始化一次;您无法将其初始化为0,然后改变主意。这是JVM的限制。

与您的第一个解决方案一样,Kotlin中的惯用解决方案是使用工厂方法。