Kotlin 数据类的主要构造函数中的局部参数

Mat*_*att 5 constructor kotlin data-class

关于data类,禁止在主构造函数中使用varval关键字,即每个参数都隐式转换为类属性。但是,有时我不希望每个参数都变成类属性。

因此,据我所知,没有机会在主构造函数中传递只能在构造函数中访问并且在实例构造完成后被遗忘的参数。这有充分的理由吗?

我认为解决这个问题的唯一方法是使用data类或使用允许非 var/val 前缀变量的辅助构造函数。然而,有很多需要传递的参数,二级构造函数会极大地膨胀类。当然,我可以将所有参数包装到另一个对象中,但这只会将问题转移到另一个地方。

是否有推荐的方法或模式来应对?

Jay*_*ard 6

你根本不受限制,你只需要做一些不同的事情即可。

数据类旨在非常清楚它们包含的内容和顺序,并且只允许主构造函数参数列表中的成员。

但是您还有其他选择:使用辅助构造函数,和/或创建与具有不同重载的类同名的顶级函数,或者在伴随对象中创建工厂方法:

data class Person(val name: String, val age: Int) {
    // secondary constructor
    constructor (name: String): this(name, 0) {
       // ... make a newborn
    }

    // factory methods in companion object
    companion object {
        fun of(name: String, birthdate: LocalDate): Person {
            return Person(name, yearsSince(birthdate))
        }
    }
}

// function with same name as class acting like a constructor
fun Person(name: String, birthdate: LocalDate): Person {
    return Person(name, yearsSince(birthdate))
}

// these all work now:

Person("Fred", 30)                                  // primary constructor
Person("Baby")                                      // secondary constructor
Person("Geoff", LocalDate.parse("12/08/1990"))      // top-level function
Person.of("Jennifer", LocalDate.parse("01/01/1981") // companion function
Run Code Online (Sandbox Code Playgroud)

您还可以通过将其设置为私有来隐藏主构造函数,但无法隐藏copy该构造函数的版本。

顺便说一句,为主构造函数提供具有此约定的数据类确实有助于序列化/反序列化库知道如何处理该类,否则这将是猜测。这是一件好事!