| <!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 Code Style and Quality Guide — 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> |
| |
| |
| |
| <!-- Use cases --> |
| <li><a href="/zh/usecases.html">应用场景</a></li> |
| |
| <!-- Powered by --> |
| <li><a href="/zh/poweredby.html">Flink 用户</a></li> |
| |
| <!-- FAQ --> |
| <li><a href="/zh/faq.html">常见问题</a></li> |
| |
| |
| <!-- Second menu section aims to support Flink users --> |
| |
| <!-- Downloads --> |
| <li><a href="/zh/downloads.html">下载</a></li> |
| |
| <!-- Getting Started --> |
| <li> |
| <a href="https://ci.apache.org/projects/flink/flink-docs-release-1.9/zh/getting-started/index.html" target="_blank">教程 <small><span class="glyphicon glyphicon-new-window"></span></small></a> |
| </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.9" target="_blank">1.9 (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">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> |
| |
| <!-- Ecosystem --> |
| <li><a href="/zh/ecosystem.html">Ecosystem</a></li> |
| |
| |
| |
| <!-- Third menu section aim to support community and contributors --> |
| |
| <!-- Community --> |
| <li><a href="/zh/community.html">社区 & 项目信息</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/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> |
| |
| |
| |
| <!-- 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 Code Style and Quality Guide — 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 & 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-language-features" id="markdown-toc-scala-language-features">Scala Language Features</a> <ul> |
| <li><a href="#where-to-use-and-not-use-scala" id="markdown-toc-where-to-use-and-not-use-scala">Where to use (and not use) Scala</a></li> |
| <li><a href="#api-parity" id="markdown-toc-api-parity">API Parity</a></li> |
| <li><a href="#language-features" id="markdown-toc-language-features">Language Features</a></li> |
| <li><a href="#coding-formatting" id="markdown-toc-coding-formatting">Coding Formatting</a></li> |
| </ul> |
| </li> |
| </ul> |
| |
| </div> |
| |
| <h2 id="scala-language-features">Scala Language Features</h2> |
| |
| <h3 id="where-to-use-and-not-use-scala">Where to use (and not use) Scala</h3> |
| |
| <p><strong>We use Scala for Scala APIs or pure Scala Libraries.</strong></p> |
| |
| <p><strong>We do not use Scala in the core APIs and runtime components. We aim to remove existing Scala use (code and dependencies) from those components.</strong></p> |
| |
| <p>⇒ This is not because we do not like Scala, it is a consequence of “the right tool for the right job” approach (see below).</p> |
| |
| <p>For APIs, we develop the foundation in Java, and layer Scala on top.</p> |
| |
| <ul> |
| <li>This has traditionally given the best interoperability for both Java and Scala</li> |
| <li>It does mean dedicated effort to keep the Scala API up to date</li> |
| </ul> |
| |
| <p>Why don’t we use Scala in the core APIs and runtime?</p> |
| |
| <ul> |
| <li>The past has shown that Scala evolves too quickly with tricky changes in functionality. Each Scala version upgrade was a rather big effort process for the Flink community.</li> |
| <li>Scala does not always interact nicely with Java classes, e.g. Scala’s visibility scopes work differently and often expose more to Java consumers than desired</li> |
| <li>Scala adds an additional layer of complexity to artifact/dependency management. |
| <ul> |
| <li>We may want to keep Scala dependent libraries like Akka in the runtime, but abstract them via an interface and load them in a separate classloader, to keep them shielded and avoid version conflicts.</li> |
| </ul> |
| </li> |
| <li>Scala makes it very easy for knowledgeable Scala programmers to write code that is very hard to understand for programmers that are less knowledgeable in Scala. That is especially tricky for an open source project with a broad community of diverse experience levels. Working around this means restricting the Scala feature set by a lot, which defeats a good amount of the purpose of using Scala in the first place.</li> |
| </ul> |
| |
| <h3 id="api-parity">API Parity</h3> |
| |
| <p>Keep Java API and Scala API in sync in terms of functionality and code quality.</p> |
| |
| <p>The Scala API should cover all the features of the Java APIs as well.</p> |
| |
| <p>Scala APIs should have a “completeness test”, like the following example from the 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="language-features">Language Features</h3> |
| |
| <ul> |
| <li><strong>Avoid Scala implicits.</strong> |
| <ul> |
| <li>Scala’s implicits should only be used for user-facing API improvements such as the Table API expressions or type information extraction.</li> |
| <li>Don’t use them for internal “magic”.</li> |
| </ul> |
| </li> |
| <li><strong>Add explicit types for class members.</strong> |
| <ul> |
| <li> |
| <p>Don’t rely on implicit type inference for class fields and methods return types:</p> |
| |
| <p><strong>Don’t:</strong> |
| <code> |
| var expressions = new java.util.ArrayList[String]() |
| </code></p> |
| |
| <p><strong>Do:</strong> |
| <code> |
| var expressions: java.util.List[String] = new java.util.ArrayList[]() |
| </code></p> |
| </li> |
| <li> |
| <p>Type inference for local variables on the stack is fine.</p> |
| </li> |
| </ul> |
| </li> |
| <li><strong>Use strict visibility.</strong> |
| <ul> |
| <li>Avoid Scala’s package private features (such as private[flink]) and use regular private/protected instead.</li> |
| <li>Keep in mind that <code>private[flink]</code> and <code>protected</code> members are public in Java.</li> |
| <li>Keep in mind that <code>private[flink]</code> still exposes all members in Flink provided examples.</li> |
| </ul> |
| </li> |
| </ul> |
| |
| <h3 id="coding-formatting">Coding Formatting</h3> |
| |
| <p><strong>Use line wrapping to structure your code.</strong></p> |
| |
| <ul> |
| <li>Scala’s functional nature allows for long transformation chains (<code>x.map().map().foreach()</code>).</li> |
| <li>In order to force implementers to structure their code, the line length is therefore limited to 100 characters.</li> |
| <li>Use one line per transformation for better maintainability.</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> · <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> |