title: Code Style and Quality Guide — Scala bookCollapseSection: false bookHidden: true
Code Style and Quality Guide — Scala
[序言]({{< relref “how-to-contribute/code-style-and-quality-preamble” >}})
[Pull Requests & Changes]({{< relref “how-to-contribute/code-style-and-quality-pull-requests” >}})
[常用编码指南]({{< relref “how-to-contribute/code-style-and-quality-common” >}})
[Java 语言指南]({{< relref “how-to-contribute/code-style-and-quality-java” >}})
[Scala 语言指南]({{< relref “how-to-contribute/code-style-and-quality-scala” >}})
[组件指南]({{< relref “how-to-contribute/code-style-and-quality-components” >}})
[格式指南]({{< relref “how-to-contribute/code-style-and-quality-formatting” >}})
Scala 语言特性
在哪儿使用(和不使用) Scala
对于 Scala 的 API 或者纯 Scala libraries,我们会选择使用 Scala。
在 core API 和 运行时的组件中,我们不使用 Scala。我们的目标是从这些组件中删除现有的 Scala 使用(代码和依赖项)。
⇒ 这并不是因为我们不喜欢 Scala,而是考虑到“用正确的工具做正确的事”的结果(见下文)。
对于 API,我们使用 Java 开发基础内容,并在上层使用 Scala。
- 这在传统上为 Java 和 Scala 提供了最佳的互通性
- 这意味着要致力于保持 Scala API 的更新
为什么我们不在 Core API 和 Runtime 中使用 Scala ?
- 过去的经验显示, Scala 在功能上的变化太快了。对于 Flink 社区来说,每次 Scala 版本升级都是一个比较棘手的处理过程。
- Scala 并不总能很好地与 Java 的类交互,例如 Scala 的可见性范围的工作方式不同,而且常常向 Java 消费者公开的内容比预期的要多。
- 由于使用 Scala ,所以 Flink 的 artifact/dependency 管理增加了一层额外的复杂性。 * 我们希望通过接口抽象,同时也在运行时保留像 Akka 这样依赖 Scala 的库,然后将它们加载到单独的类加载器中,以保护它们并避免版本冲突。
- Scala 让懂 Scala 的程序员很容易编写代码,而对于不太懂 Scala 的程序员来说,这些代码很难理解。对于一个拥有不同经验水平的广大社区的开源项目来说,这尤其棘手。解决这个问题意味着大量限制 Scala 特性集,这首先就违背了使用 Scala 的很多目的。
API 等价
保持 Java API 和 Scala API 在功能和代码质量方面的同步。
Scala API 也应该涵盖 Java API 的所有特性。
Scala API 应该有一个“完整性测试”,就如下面 DataStream API 的示例中的一样: https://github.com/apache/flink/blob/master/flink-streaming-scala/src/test/scala/org/apache/flink/streaming/api/scala/StreamingScalaAPICompletenessTest.scala
语言特性
- 避免 Scala 隐式转换。
- Scala 的隐式转换应该只用于面向用户的 API 改进,例如 Table API 表达式或类型信息提取。
- 不要把它们用于内部 “magic”。
- 为类成员添加显式类型。
- 用严格的可见性。
- 避免使用 Scala 的包私有特性(如 private[flink]),而是使用常规 private/protected 替代。
- 请注意:在 Java 中,
private[flink] 和 protected 的成员是公开的。 - 请注意:在 Flink 提供的示例中,
private[flink] 仍然会暴露所有成员。
编码格式
使用换行来构造你的代码。
- Scala 的函数性质允许长的转换链 (
x.map().map().foreach()). - 为了强制让实现者构造其代码,因此将行长度限制为 100 个字符以内。
- 为了更好的可维护性,每次转换使用一行。