1

我对 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])
    }
}
4

1 回答 1

1

超级构造函数调用必须是构造函数的第一条语句,并且只能出现一次。此外,每个都val必须只初始化一次;你不能用 0 初始化它然后改变主意。这是 JVM 限制。

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

于 2018-07-26T16:16:18.730 回答