首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala风格的元素?

Scala风格的元素?
EN

Stack Overflow用户
提问于 2009-08-15 14:07:44
回答 5查看 5.4K关注 0票数 43

白天,我编写C#。我做的每件事都要经过微软的代码分析和静态分析工具,所以我的C#有一个非常规则的结构和布局。显然,我写的代码有一定的风格。这在一定程度上是因为我别无选择(如果我错过了逗号前的空格,它就不会编译),但拥有看起来正常的代码,知道在哪里查找东西等也是很好的。

每到周末,我就会进入Scala。看一下Scala API和Lift web框架的源代码,我显然看不到任何标准化的风格。例如,我突然想到的一件事是,每个类都没有单独的文件。括号和大括号缺乏一致性是另一个例子。

我知道这可能有几个原因:首先,对于开源(或业余爱好)代码,确保一个明显的方法没有完全文档化是不太重要的。其次,像case类这样的东西将20行的类声明减少到了一行。第三,C#是一种更“扁平化”的语言:除非它是一个复杂的LINQ语句,否则嵌套的括号、大括号和括号的数量不会那么深。在Scala中,事情往往会变得有点嵌套。

普通的Scala用户有他们坚持的特定风格吗?我是不是太愚蠢了,为了外星人的习惯,把一个一行case-class放在它自己的文件里?有什么建议吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-08-15 14:51:53

在一个文件中包含多个类和对象在Scala中被认为是很好的形式,只要这些类紧密相关。

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

代码语言:javascript
复制
//  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))
}

在关键字和圆括号之间应该有空格,但在方法名和后面的圆括号之间不应该有空格。对于运算符表示法,似乎没有关于括号的可接受样式--或者何时使用该表示法,但在这种表示法中,非字母数字方法周围应该有空格。

代码语言:javascript
复制
//  keywords
if (foo) ...

//  dot notation
foo.doSomething(bar)

//  operator notation
foo doSomething bar
foo + bar

在例外情况下,当使用+连接字符串时,建议的样式是不要在它周围使用空格。例如:

代码语言:javascript
复制
//  concatenate strings
println("Name: "+person.name+"\tAge: "+person.age)

可以是一行程序的声明应该是一行程序,除非嵌套不明显。

代码语言:javascript
复制
//  one-liners
lazy val foo = calculateFoo
def square(x: Int) = x * x

不需要参数并且没有副作用的方法应该不使用括号,但Java方法除外,Java方法应该与括号一起使用。有副作用的无参数方法应该与括号一起使用。

代码语言:javascript
复制
//  without side-effects
val x = foo.length
val y = bar.coefficient

//  with side-effects
foo.reverse()

包含单个表达式的声明不应包含在大括号内,除非其他语法考虑使其无法实现。将表达式包含在括号中以启用多行表达式是可以接受的,但我几乎没有看到这种用法。

代码语言:javascript
复制
//  single-line expression
def sum(list: List[Int]): Int = if (!list.isEmpty) list reduceLeft (_ + _) else 0

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

在形成理解中,保持生成器和条件垂直对齐似乎是一种被接受的风格。至于yield,我看到它既与for对齐,又缩进。

代码语言:javascript
复制
//  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)

垂直对齐类声明的参数也是一种可接受的样式。

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

大括号应从声明的同一行开始,并与该行垂直对齐结束。

代码语言:javascript
复制
//  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的函数--来说,期望的样式应该是省略方法的类型和等号:

代码语言:javascript
复制
//  procedures
def complain {
  println("Oh, no!")
}

然而,有些人认为这种风格容易出错,因为缺少等号会将返回Unit以外的内容的函数更改为过程。

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

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

代码语言:javascript
复制
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
}

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

不推荐使用下划线字符-- _,因为该字符在Scala中有许多特殊含义。这些标识符规则可以在Odersky,Spoon & Venners的《在Scala中编程》的第141和142页找到。

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

更重要的是,可能并没有太多统一的约定。其中一个原因可能是Scala吸引了许多不同背景的人,比如函数式语言专家、Java程序员和Web2.0爱好者。

票数 45
EN

Stack Overflow用户

发布于 2009-11-12 08:06:12

现在有了一个完整的Scala风格指南,它已经被proposed to the community。它甚至还不是官方的,但(据我所知)它是社区接受的约定的唯一编码。

  • PDF
  • Text
票数 12
EN

Stack Overflow用户

发布于 2012-10-11 18:31:55

现在可以使用了。它不是100%官方的(位于"Community-driven documentation for Scala“网站上),但似乎是Scala最标准的风格指南。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1281977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档