Kotlin 计算构造函数中未显示的字段

Kotlin 计算构造函数中未显示的字段,kotlin,Kotlin,假设我有一个包含3个字段的类:a、B和C。我可以通过两种方式创建该类的实例:将所有字段传递给构造函数,或者仅传递a,其他属性将基于a进行计算 class MyClass { val A: String val B: String val C: String constructor(A: String, B: String, C: String) { this.A = A this.B = B this.C = C

假设我有一个包含3个字段的类:a、B和C。我可以通过两种方式创建该类的实例:将所有字段传递给构造函数,或者仅传递a,其他属性将基于a进行计算

class MyClass {
    val A: String
    val B: String
    val C: String

    constructor(A: String, B: String, C: String) {
        this.A = A
        this.B = B
        this.C = C
    }

    constructor(A: String) {
        this.A = A
        val (_B, _C) = Calculator.calculate(A)
        this.B = _B
        this.C = _C
    }
}

这种方法使用两个辅助构造函数,而不使用主构造函数。但在我看来,它看起来很重。是否可以以更优雅的方式重写此逻辑?

您可以将其作为数据类编写,至少可以像这样去掉默认构造函数

data class MyClass(
    val A: String,
    val B: String,
    val C: String
) {
    constructor(A: String, calculated: Pair<String, String> = calculate()) : this(
        A,
        calculated.first,
        calculated.second
    )
}

fun calculate() : Pair<String, String> = "this" to "that"
数据类MyClass(
瓦尔:字符串,
瓦尔B:字符串,
val C:字符串
) {
构造函数(A:String,computed:Pair=calculate()):这个(
A.
首先,
秒
)
}
fun calculate():将“这个”与“那个”配对

也许以下内容适合您。您可能想用实际类型替换
Pair
,然后改为

class MyClass(
        val A: String,
        val BC : Pair<String, String>
) {
    constructor(A: String, B: String, C: String) : this(A, B to C) // is this then even needed?
    constructor(A : String) : this(A, Calculator.calculate(A))
}
也许您更需要一些东西来传递函数(因为您还使用了
Calculator.calculation(a)
)。然后,您可能希望添加以下内容作为构造函数:

constructor(A : String, func: (String) -> Pair<String, String> = Calculator::calculate) : this(A, func(A))

我个人最喜欢的是滥用对象调用操作符:

class MyClass(val A: String, val B: String, val C: String) {

    companion object {
        operator fun invoke(A: String): MyClass {
            val (B, C) = Calculator.calculate(A)
            return MyClass(A, B, C)
        }
    }
}

计算
返回什么?由于它是可分解的,同一类型在
MyClass
本身是否可以?它返回
Pair
我的错误,我把构造函数实现搞砸了。现在修复了。关于你在回答中的评论:我不这么认为。。。但是您仍然可以为此添加一个额外的构造函数,例如:
构造函数(A:String,BC:Pair):this(A,BC.first,BC.second)
它是否是数据类在这里并不相关。我只不喜欢这里的“滥用”一词;-)我喜欢该变体的地方是,您可以使用
同伴
上的扩展函数轻松地将此类函数移到类外,因此也可以轻松地添加其他变体…我甚至可以对调用使用直接赋值。。。它没有那么多功能,因此您仍然可以轻松掌握它,例如:
operator fun invoke(A:String)=Calculator.calculate(A)。让{(B,C)->MyClass(A,B,C)}
(适当的新行)@Roland I尽管已经编辑了我的答案,但还是放弃了它。在一般情况下,可能不止一个外部计算,而
版本可能会让事情变得糟糕。
constructor(A : String, func: (String) -> Pair<String, String> = Calculator::calculate) : this(A, func(A))
class MyClass(val A: String,
              func: (String) -> Pair<String, String> = Calculator::calculate) {
    val B: String
    val C: String

    init {
        func(A).also { (newB, newC) ->
            B = newB
            C = newC
        }
    }
}
MyClass("myA") { /* _ -> */ /* A -> */
   "myCalculatedB" to "C"
}
class MyClass(val A: String, val B: String, val C: String) {

    companion object {
        operator fun invoke(A: String): MyClass {
            val (B, C) = Calculator.calculate(A)
            return MyClass(A, B, C)
        }
    }
}