blob: 103e04671f3210ccc2c07dba560065b1833e0f5b [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Apache Flink: Apache Flink 代码样式与质量指南 — Scala</title>
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/flink.css">
<link rel="stylesheet" href="/css/syntax.css">
<!-- Blog RSS feed -->
<link href="/blog/feed.xml" rel="alternate" type="application/rss+xml" title="Apache Flink Blog: RSS feed" />
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<!-- We need to load Jquery in the header for custom google analytics event tracking-->
<script src="/js/jquery.min.js"></script>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<!-- Main content. -->
<div class="container">
<div class="row">
<div id="sidebar" class="col-sm-3">
<!-- Top navbar. -->
<nav class="navbar navbar-default">
<!-- The logo. -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<div class="navbar-logo">
<a href="/zh/">
<img alt="Apache Flink" src="/img/flink-header-logo.svg" width="147px" height="73px">
</a>
</div>
</div><!-- /.navbar-header -->
<!-- The navigation links. -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-main">
<!-- First menu section explains visitors what Flink is -->
<!-- What is Stream Processing? -->
<!--
<li><a href="/zh/streamprocessing1.html">What is Stream Processing?</a></li>
-->
<!-- What is Flink? -->
<li><a href="/zh/flink-architecture.html">Apache Flink 是什么?</a></li>
<!-- What is Stateful Functions? -->
<li><a href="/zh/stateful-functions.html">What is Stateful Functions?</a></li>
<!-- Use cases -->
<li><a href="/zh/usecases.html">应用场景</a></li>
<!-- Powered by -->
<li><a href="/zh/poweredby.html">Flink 用户</a></li>
&nbsp;
<!-- Second menu section aims to support Flink users -->
<!-- Downloads -->
<li><a href="/zh/downloads.html">下载</a></li>
<!-- Getting Started -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">教程<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="https://ci.apache.org/projects/flink/flink-docs-release-1.11/zh/getting-started/index.html" target="_blank">With Flink <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-statefun-docs-release-2.1/getting-started/project-setup.html" target="_blank">With Flink Stateful Functions <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="/zh/training.html">Training Course</a></li>
</ul>
</li>
<!-- Documentation -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">文档<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="https://ci.apache.org/projects/flink/flink-docs-release-1.11" target="_blank">Flink 1.11 (Latest stable release) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-docs-master" target="_blank">Flink Master (Latest Snapshot) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-statefun-docs-release-2.1" target="_blank">Flink Stateful Functions 2.1 (Latest stable release) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-statefun-docs-master" target="_blank">Flink Stateful Functions Master (Latest Snapshot) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
</ul>
</li>
<!-- getting help -->
<li><a href="/zh/gettinghelp.html">获取帮助</a></li>
<!-- Blog -->
<li><a href="/blog/"><b>Flink 博客</b></a></li>
<!-- Flink-packages -->
<li>
<a href="https://flink-packages.org" target="_blank">flink-packages.org <small><span class="glyphicon glyphicon-new-window"></span></small></a>
</li>
&nbsp;
<!-- Third menu section aim to support community and contributors -->
<!-- Community -->
<li><a href="/zh/community.html">社区 &amp; 项目信息</a></li>
<!-- Roadmap -->
<li><a href="/zh/roadmap.html">开发计划</a></li>
<!-- Contribute -->
<li><a href="/zh/contributing/how-to-contribute.html">如何参与贡献</a></li>
<ul class="nav navbar-nav navbar-subnav">
<li >
<a href="/zh/contributing/contribute-code.html">贡献代码</a>
</li>
<li >
<a href="/zh/contributing/reviewing-prs.html">审核 Pull Request</a>
</li>
<li >
<a href="/zh/contributing/code-style-and-quality-preamble.html">代码样式与质量指南</a>
</li>
<li >
<a href="/zh/contributing/contribute-documentation.html">贡献文档</a>
</li>
<li >
<a href="/zh/contributing/docs-style.html">Documentation Style Guide</a>
</li>
<li >
<a href="/zh/contributing/improve-website.html">贡献网站</a>
</li>
</ul>
<!-- GitHub -->
<li>
<a href="https://github.com/apache/flink" target="_blank">Flink on GitHub <small><span class="glyphicon glyphicon-new-window"></span></small></a>
</li>
&nbsp;
<!-- Language Switcher -->
<li>
<a href="/contributing/code-style-and-quality-scala.html">English</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-bottom">
<hr />
<!-- Twitter -->
<li><a href="https://twitter.com/apacheflink" target="_blank">@ApacheFlink <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<!-- Visualizer -->
<li class=" hidden-md hidden-sm"><a href="/visualizer/" target="_blank">Plan Visualizer <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<hr />
<li><a href="https://apache.org" target="_blank">Apache Software Foundation <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li>
<style>
.smalllinks:link {
display: inline-block !important; background: none; padding-top: 0px; padding-bottom: 0px; padding-right: 0px; min-width: 75px;
}
</style>
<a class="smalllinks" href="https://www.apache.org/licenses/" target="_blank">License</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
<a class="smalllinks" href="https://www.apache.org/security/" target="_blank">Security</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
<a class="smalllinks" href="https://www.apache.org/foundation/sponsorship.html" target="_blank">Donate</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
<a class="smalllinks" href="https://www.apache.org/foundation/thanks.html" target="_blank">Thanks</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</nav>
</div>
<div class="col-sm-9">
<div class="row-fluid">
<div class="col-sm-12">
<h1>Apache Flink 代码样式与质量指南 — Scala</h1>
<ul class="list-group" style="padding-top: 30px; font-weight: bold;">
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-preamble.html">
序言
</a>
</li>
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-pull-requests.html">
Pull Requests &amp; Changes
</a>
</li>
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-common.html">
常用编码指南
</a>
</li>
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-java.html">
Java 语言指南
</a>
</li>
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-scala.html">
Scala 语言指南
</a>
</li>
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-components.html">
组件指南
</a>
</li>
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-formatting.html">
格式指南
</a>
</li>
</ul>
<hr />
<div class="page-toc">
<ul id="markdown-toc">
<li><a href="#scala-" id="markdown-toc-scala-">Scala 语言特性</a> <ul>
<li><a href="#scala" id="markdown-toc-scala">在哪儿使用(和不使用) Scala</a></li>
<li><a href="#api-" id="markdown-toc-api-">API 等价</a></li>
<li><a href="#section" id="markdown-toc-section">语言特性</a></li>
<li><a href="#section-1" id="markdown-toc-section-1">编码格式</a></li>
</ul>
</li>
</ul>
</div>
<h2 id="scala-">Scala 语言特性</h2>
<h3 id="scala">在哪儿使用(和不使用) Scala</h3>
<p><strong>对于 Scala 的 API 或者纯 Scala libraries,我们会选择使用 Scala。</strong></p>
<p><strong>在 core API 和 运行时的组件中,我们不使用 Scala。我们的目标是从这些组件中删除现有的 Scala 使用(代码和依赖项)。</strong></p>
<p>⇒ 这并不是因为我们不喜欢 Scala,而是考虑到“用正确的工具做正确的事”的结果(见下文)。</p>
<p>对于 API,我们使用 Java 开发基础内容,并在上层使用 Scala。</p>
<ul>
<li>这在传统上为 Java 和 Scala 提供了最佳的互通性</li>
<li>这意味着要致力于保持 Scala API 的更新</li>
</ul>
<p>为什么我们不在 Core API 和 Runtime 中使用 Scala ?</p>
<ul>
<li>过去的经验显示, Scala 在功能上的变化太快了。对于 Flink 社区来说,每次 Scala 版本升级都是一个比较棘手的处理过程。</li>
<li>Scala 并不总能很好地与 Java 的类交互,例如 Scala 的可见性范围的工作方式不同,而且常常向 Java 消费者公开的内容比预期的要多。</li>
<li>由于使用 Scala ,所以 Flink 的 artifact/dependency 管理增加了一层额外的复杂性。
<ul>
<li>我们希望通过接口抽象,同时也在运行时保留像 Akka 这样依赖 Scala 的库,然后将它们加载到单独的类加载器中,以保护它们并避免版本冲突。</li>
</ul>
</li>
<li>Scala 让懂 Scala 的程序员很容易编写代码,而对于不太懂 Scala 的程序员来说,这些代码很难理解。对于一个拥有不同经验水平的广大社区的开源项目来说,这尤其棘手。解决这个问题意味着大量限制 Scala 特性集,这首先就违背了使用 Scala 的很多目的。</li>
</ul>
<h3 id="api-">API 等价</h3>
<p>保持 Java API 和 Scala API 在功能和代码质量方面的同步。</p>
<p>Scala API 也应该涵盖 Java API 的所有特性。</p>
<p>Scala API 应该有一个“完整性测试”,就如下面 DataStream API 的示例中的一样: <a href="https://github.com/apache/flink/blob/master/flink-streaming-scala/src/test/scala/org/apache/flink/streaming/api/scala/StreamingScalaAPICompletenessTest.scala">https://github.com/apache/flink/blob/master/flink-streaming-scala/src/test/scala/org/apache/flink/streaming/api/scala/StreamingScalaAPICompletenessTest.scala</a></p>
<h3 id="section">语言特性</h3>
<ul>
<li><strong>避免 Scala 隐式转换。</strong>
<ul>
<li>Scala 的隐式转换应该只用于面向用户的 API 改进,例如 Table API 表达式或类型信息提取。</li>
<li>不要把它们用于内部 “magic”。</li>
</ul>
</li>
<li><strong>为类成员添加显式类型。</strong>
<ul>
<li>
<p>对于类字段和方法返回类型,不要依赖隐式类型推断:</p>
<p><strong>不要这样:</strong>
<code>
var expressions = new java.util.ArrayList[String]()
</code></p>
<p><strong>要这样:</strong>
<code>
var expressions: java.util.List[String] = new java.util.ArrayList[]()
</code></p>
</li>
<li>
<p>堆栈上局部变量的类型推断是可以的。</p>
</li>
</ul>
</li>
<li><strong>用严格的可见性。</strong>
<ul>
<li>避免使用 Scala 的包私有特性(如 private[flink]),而是使用常规 private/protected 替代。</li>
<li>请注意:在 Java 中,<code>private[flink]</code><code>protected</code> 的成员是公开的。</li>
<li>请注意:在 Flink 提供的示例中, <code>private[flink]</code> 仍然会暴露所有成员。</li>
</ul>
</li>
</ul>
<h3 id="section-1">编码格式</h3>
<p><strong>使用换行来构造你的代码。</strong></p>
<ul>
<li>Scala 的函数性质允许长的转换链( <code>x.map().map().foreach()</code> )。</li>
<li>为了强制让实现者构造其代码,因此将行长度限制为 100 个字符以内。</li>
<li>为了更好的可维护性,每次转换使用一行。</li>
</ul>
</div>
</div>
</div>
</div>
<hr />
<div class="row">
<div class="footer text-center col-sm-12">
<p>Copyright © 2014-2019 <a href="http://apache.org">The Apache Software Foundation</a>. All Rights Reserved.</p>
<p>Apache Flink, Flink®, Apache®, the squirrel logo, and the Apache feather logo are either registered trademarks or trademarks of The Apache Software Foundation.</p>
<p><a href="/privacy-policy.html">Privacy Policy</a> &middot; <a href="/blog/feed.xml">RSS feed</a></p>
</div>
</div>
</div><!-- /.container -->
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.matchHeight/0.7.0/jquery.matchHeight-min.js"></script>
<script src="/js/codetabs.js"></script>
<script src="/js/stickysidebar.js"></script>
<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-52545728-1', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>