Scala 风格的元素? [英] Elements of Scala Style?

查看:21
本文介绍了Scala 风格的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

白天我写 C#.我所做的一切都经过 Microsoft 代码分析和静态分析工具,所以我的 C# 具有非常规则的结构和布局.很明显,我用某种风格编写代码.这是部分原因,因为我别无选择(如果我错过了逗号前的空格,它将无法编译),但拥有定期查看的代码、知道在哪里查找内容等也很好.

By day I write C#. Everything I do goes through Microsoft code analysis and static analysis tools, so my C# has a very regular structure and layout. Obviously, I write code with a certain style. It is partially, because I have no choice (it won't compile if I miss out a space before that comma), but it's also nice to have regular looking code, knowing where to look for things, etc.

周末我会进入 Scala.查看 Scala API 和 Lift 网络框架源代码,我显然看不到任何标准化风格.例如,让我印象深刻的一件事是每个类都缺少一个单独的文件.括号和大括号缺乏一致性是另一个例子.

At the weekends I'm getting into Scala. Looking at the Scala API and Lift web framework source, I can't obviously see any standardised style. One thing that jumps out at me, for example, is the lack of a separate file per class. The lack of consistency with brackets and braces is another example.

我理解这可能有几个原因:首先,使用开源(或业余爱好)代码确保没有完全记录明显方法的优先级较低.其次,case classes 之类的东西将 20 行类声明减少到一行.第三,C# 是一种更扁平化"的语言:除非它是一个复杂的LINQ 语句,否则嵌套括号、大括号和方括号没有那么深.在 Scala 中,事情往往有点嵌套.

I understand that there are probably a few reasons driving this: firstly, with open source (or hobby) code making sure that an obvious method isn't completely documented is less of a priority. Secondly, things like case classes cut down 20-line class declarations into a single line. Thirdly, C# is a much 'flatter' language: unless it's a complex LINQ statement, the numbers of nested parens, braces and brackets isn't that deep. In Scala, things tend to get a little nested.

普通 Scala 用户是否有他们坚持的特定风格?为了[外星人]约定,我是否只是愚蠢地将单行案例类放在自己的文件中?有什么提示吗?

Do regular Scala users have a specific style that they stick to? Am I just being stupid putting a one-line case-class in its own file for the sake of [alien] convention? Any tips?

推荐答案

在单个文件中拥有多个类和对象在 Scala 中被认为是一种很好的形式,只要这些类紧密相关.

Having multiple classes and objects inside a single file is considered good form in Scala, as long as the classes are tightly related.

虽然不是必需的,但方法返回的类型——在特征、类或对象上声明的命名函数——应该为非私有方法声明.: 之后应该有空格,但之前不能.

While not necessary, the type returned by a method -- a named function declared on a trait, class or object -- is expected to be declared for non-private methods. Spaces are expected after :, but not before it.

//  methods declared on a class, trait or object
def length: Int = ...
def multiply(other: Foo): Foo = ...

def hypotenuse(a: Double, b: Double): Double = {
  //  function inside a method, so effectively private
  def square(x: Double) = x * x

  math.sqrt(square(a) + square(b))
}

关键字和括号之间需要空格,但方法名和后面的括号之间不能有空格,用点表示法.对于运算符表示法,似乎没有关于括号的可接受风格——或者何时使用该表示法,就此而言,但在这种表示法中,非字母数字方法周围需要空格.

Spaces are expected between keywords and parenthesis, but not between a method name and the following parenthesis, in dot notation. For operator notation, there doesn't seem to be an accepted style regarding parenthesis -- or when to use that notation, for that matter, but spaces are expected around non-alphanumeric methods in such notation.

//  keywords
if (foo) ...

//  dot notation
foo.doSomething(bar)

//  operator notation
foo doSomething bar
foo + bar

例外,当用 + 连接字符串时,推荐的风格是不要在它周围使用空格.例如:

Exceptionally, when concatenating strings with +, the recommended style is not to use spaces around it. For example:

//  concatenate strings
println("Name: "+person.name+"\tAge: "+person.age)

可以是单行的声明应该是单行的,除非嵌套不明显.

Declarations that can be one-liners are expected to be one-liners, unless the nesting isn't obvious.

//  one-liners
lazy val foo = calculateFoo
def square(x: Int) = x * x

不期望参数且没有副作用的方法应该不带括号使用,但Java方法除外,它们期望带括号使用.有副作用的无参数方法应该带括号使用.

Methods that do not expect parameters, and do not have side effects, are supposed to be used without parenthesis, except for Java methods, which are expected to be used with parenthesis. Parameter-less methods with side effects are supposed to be used with parenthesis.

//  without side-effects
val x = foo.length
val y = bar.coefficient

//  with side-effects
foo.reverse()

包含单个表达式的声明不应包含在花括号内,除非其他语法考虑使之成为不可能.接受将表达式括在括号内以启用多行表达式,但我很少看到它的用途.

Declarations which contains a single expression are expected not to be enclosed inside curly braces unless other syntactic considerations make that impossible. Enclosing an expression within parenthesis to enable multi-line expressions is accepted, but I have seen little use of that.

//  single-line expression
def sum(list: List[Int]): Int = if (!list.isEmpty) list reduceLeft (_ + _) else 0

//  multi-line expression
val sum = (
  getItems
  reduceLeft (_ + _)
)

在 for-comprehensions 中,保持生成器和条件垂直对齐似乎是一种公认​​的风格.至于 yield,我已经看到它与 for 对齐并缩进.

In for-comprehensions, keeping generators and conditions vertically aligned seems to be an accepted style. As for yield, I have seen it both aligned with for and indented.

//  for-comprehensions
val squares =
  for (x <- numbers)
    yield x * x

// Curly brackets-style identation
val cells = for {
  x <- columns
  y <- rows
  if x != y
} yield Cell(x, y)

// Parameter-style identation
val cells = for (x <- columns;
                 y <- rows;
                 if x != y)
            yield Cell(x, y)

垂直对齐类声明的参数也是可接受的风格.

It's also accepted style to vertically align parameters of a class declaration.

说到缩进,两个空格是公认的约定.

Speaking of indentation, two-spaces is the accepted convention.

花括号应该在声明的同一行开始,并以与该行本身垂直对齐的方式结束.

Curly braces are expected to start on the same line of the declaration, and end vertically aligned with that line by itself.

//  another example
def factorial(n: Int): Int = {
  def fact(n: Int, acc: Int): Int = n match {
    case 0 => acc
    case x => fact(x - 1, x * acc)
  }

  fact(n, 1)
}

对于过程——返回类型为Unit的函数——预期的样式应该是省略方法的类型和等号:

For procedures -- functions whose return type is Unit --, the expected style was supposed to be to leave out the type of the method and the equal sign:

//  procedures
def complain {
  println("Oh, no!")
}

有些人认为这种风格容易出错,但是,因为错过等号会将返回除 Unit 以外的其他内容的函数更改为过程.

Some people think this style is error prone, however, as a missed equal sign will change a function returning something other than Unit into a procedure.

标识符以驼峰式写成(例如:identifiersHaveHumps),就像在 Java 中一样.对于字段、方法参数、局部变量和函数的名称,以小写字母开头.对于类、特征和类型,以大写字母开头.

Identifiers are written in camel case (eg: identifiersHaveHumps), like in Java. For names of fields, method parameters, local variables and functions, start with a lower case letter. For classes,traits and types, start with an upper case letter.

与Java约定不同的是常量名.在 Scala 中,实践是使用以大写字母开头的标准驼峰式大小写.例如 Pi 而不是 PI,XOffset 而不是 X_OFFSET.任何单例通常都遵循此规则.对于大小写匹配,以这种方式表示常量和单例具有实际的后果:

Departing from Java convention are constant names. In Scala, the practice is to use standard camel case starting with an upper case letter. For example Pi and not PI, XOffset and not X_OFFSET. This rule is usually followed by any singleton. Having a constants and singletons be represented that way has a practical consequence, for case matches:

import scala.Math.Pi

val pi = Pi // this identifier will be shadowed by the identifier in the function below

def isPi(n: Double): Boolean = n match {
  case Pi => println("I got a true Pi."); true
  case pi => println("I got "+pi+" and bounded it to an identifier named pi."); false
}

包名称以小写字母开头.当在导入语句中区分什么是包和什么不是包时,这特别有用.在前面的例子中,Math 不是一个包(它是一个单例),因为它以大写字母开头.

Package names are written beginning with a lower case letter. This is particularly helpful when distinguishing in an import statement what is a package and what is not. In the previous example, Math is not a package (it's a singleton), as it begins with an upper case letter.

不推荐使用下划线字符 -- _ -- ,因为该字符在 Scala 中有很多特殊含义.这些标识符规则可以在 Odersky、Spoon & 编写的 Scala 编程的第 141 和 142 页中找到.维纳斯.

Using the underline character -- _ -- is not recommended, as that character has many special meanings in Scala. These rules for identifiers can be found on pages 141 and 142 of Programming in Scala, by Odersky, Spoon & Venners.

现在,我想不起来其他情况,但请随时要求澄清具体问题.其中一些规则是明确规定的,其他规则更多的是社区共识.我试图忽略我自己的偏好,但我可能失败了.

Right now, I can't recall other situations, but feel free to ask for clarification on specific points. Some of these rules were explicitly stated, others are more of a community consensus. I tried to leave out my own preferences, but I may have failed.

更重要的是,也许没有太多统一的约定.原因之一可能是 Scala 吸引了来自许多不同背景的人,例如函数式语言专家、Java 程序员和 Web 2.0 爱好者.

More importantly, perhaps, there just isn't really much of an unified convention. One reason for that may be that Scala is attracting people from many very different backgrounds, such as functional language mavens, Java programmers and web 2.0 enthusiasts.

这篇关于Scala 风格的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆