代码之家  ›  专栏  ›  技术社区  ›  Jan B. HDR

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

  •  4
  • Jan B. HDR  · 技术社区  · 7 年前

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

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

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

    是否有一个建议的方法或模式来应对?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Jayson Minard    7 年前

    你完全不受限制,你只需要做一些不同的事情。

    数据类的目的是非常清楚它们包含的内容和顺序,并且只允许 主构造器 参数列表。

    但你还有其他选择:使用 二级建造师 和/或 创建顶级函数 与具有不同重载的类同名,或创建 工厂方法 在伴生对象中:

    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
    

    也可以通过将主构造函数设为私有来隐藏它,但不能隐藏 copy 该构造函数的版本。

    顺便说一下,让主构造函数的数据类具有这个约定,真的有助于序列化/反序列化库了解如何处理否则可能是猜测的类。这是件好事!

        2
  •  0
  •   FilipRistic    7 年前

    我要说的第一件事是,这是我个人的观点,所以,拿它来说吧。

    来自官方考特林 documentation

    我们经常创建以保存数据为主要目的的类。在这样的类中,一些标准功能和实用功能通常可以从数据中机械地派生出来。

    所以 data classes 应该用作数据容器,它们不应该包含太多逻辑。

    从我的角度来看,当您想将某个东西传递给构造函数但类不存储该数据时,可能有一些逻辑与之相关。

    要执行此操作的常见情况是:

    1. 使用某个标志更改构造函数的行为

    2. 传递一些类,这些类包装所有需要的数据,然后将其提取到每个单独的字段中。

    在第一种情况下,我们清楚地看到这不是 data class 用例。

    第二种情况是糟糕的代码,它引入了对另一个类的不必要依赖,并隐藏了该类实际需要的东西。

    构造函数应该很简单,它们获取类所需的数据并将其绑定到字段中,不应该存在太多的逻辑,应该由使用构造函数准备所有数据的人员决定,如果在创建新实例时有一些可重复的代码,那么最好使用 factory method 把它包起来。