= GEP-14: 记录类 :icons: font .Metadata **** [horizontal,options="compact"] *编号*:: GEP-14 *标题*:: 记录类 *版本*:: 1 *类型*:: 功能 *状态*:: 草稿 *负责人*:: Paul King *创建日期*:: 2021-10-26 *最后修改日期* :: 2021-10-26 **** == 摘要 记录类,或简称 _记录_,是一种特殊类型的类,用于建模普通的聚合数据。它们提供了一种紧凑的语法,比普通类所需的仪式更少。Groovy 已经有了 `@Immutable` 和 `@Canonical` 等 AST 转换,它们已经极大地减少了仪式,但记录已在 Java 中引入,Groovy 中的记录类旨在与 Java 记录类对齐。 === 动机 关于记录的一般概念的动机,请参阅下面的参考资料和有用链接部分。总的来说,对于普通数据聚合的特殊情况,可以编写非常简洁的类,例如: [source,groovy] ---- record Point3D(int x, int y, int z) { } ---- 或: [source,groovy] ---- record Person(String firstName, String lastName) { } ---- 此类具有自动的 `toString`、`hashCode` 和 `equals` 方法以及自动的元组构造函数。所有这些都考虑了类的属性(称为记录组件)。 === 要求 主要要求是在合适的 JDK 版本(16+)上编译时提供与 Java 记录类等效的功能。通过 _等效功能_,以下方面是相关的: * 支持在编写记录时减少仪式。 * 在字节码级别存储适当的信息,以便 Groovy 记录被 Java 识别。我们将具有此类字节码信息的类称为 _原生_ 记录。 * 尽可能保持 Java 语法兼容性,包括紧凑的构造函数语法。 ==== 非目标 * 在支持预览模式下记录的 JDK 版本上提供原生记录支持 === 设计考虑 * 许多 Groovy AST 转换已经提供了与 Java 记录的某些功能重叠的功能,例如 `@ToString` 通过提供声明性机制来实现 _自动_ `toString` 方法来帮助减少仪式。在合理的情况下,Groovy 的记录实现应该利用此类现有功能。 * 即使可以将现有的 Groovy AST 转换组合起来以实现模拟记录功能,但提供这些部分的预打包以简洁地镜像记录功能是值得的。记录不应给学习或使用 Groovy 的 Java 开发人员带来任何额外的障碍。 * Groovy 现有的 AST 转换提供了额外的自定义选项和额外的样板代码减少选项。这些应与 Groovy 记录一起提供(在合理的情况下)。 * 鉴于 Groovy 现有的 AST 转换适用于 JDK16 之前的 JDK 版本,Groovy 的记录功能可以允许创建 _类记录_ 类。与 _原生_ 记录不同,这些类在字节码级别不包含记录信息,但否则将遵循与原生记录相同的约定。此类类将使用注解存储记录信息。它们将被 Groovy 编译器识别,但不会被 Java 编译器识别。 * 鉴于记录主要设计为数据聚合,Groovy 记录默认情况下为 `@CompileStatic`。 === Groovy 特殊功能 * 支持 Groovy 的命名参数语法 * 支持 Groovy 的 `getAt` 方法用于按位置访问组件 * 支持 Groovy 的默认参数概念 * 支持其他语言中发现的额外辅助方法,例如 Kotlin 数据类和 Scala 案例类。候选包括 `copyWith`、`size`、`toMap`、`toList`。 * 支持记录的解构 ==== 初始实现 * 提供一个 `@RecordType` 注解收集器,该收集器收集适合提供所需功能的现有 AST 转换。 * 提供一个 `@RecordBase` AST 转换,该转换封装现有转换中未找到的任何特殊处理。 * 提供一个 `@RecordOptions` 注解,该注解允许自定义构建的记录实现。 * 在语法中提供对 `record` 关键字的支持,该关键字可以代替 `@RecordType` 注解使用。 == 参考资料和有用链接 * https://openjdk.org/jeps/395[JEP 395: 记录] * https://openjdk.org/jeps/384[JEP 384: 记录 (第二预览版)] * https://openjdk.org/jeps/359[JEP 359: 记录 (预览版)] * https://docs.oracle.com/en/java/javase/16/language/records.html[记录类] Java 文档 * https://kotlinlang.org/docs/data-classes.html[Kotlin 数据类] * https://docs.scala-lang.org.cn/tour/case-classes.html[Scala 案例类] === 参考实现 https://github.com/apache/groovy/pull/1375 https://github.com/apache/groovy/pull/1633 https://github.com/apache/groovy/pull/1645 === JIRA 问题 * https://issues.apache.org/jira/browse/GROOVY-9754[GROOVY-9754: 提供类似记录的等效功能] * https://issues.apache.org/jira/browse/GROOVY-10240[GROOVY-10240: 支持记录语法] * https://issues.apache.org/jira/browse/GROOVY-10298[GROOVY-10298: 优化记录,不使用系统属性] * https://issues.apache.org/jira/browse/GROOVY-10338[GROOVY-10338: 使用额外的辅助方法增强记录] == 更新历史 1 (2021-10-26) 初稿 2 (2021-11-06) 更新以与 4.0.0-beta-2 对齐