白天我写C#.我所做的一切都通过Microsoft代码分析和静态分析工具进行,因此我的C#具有非常规则的结构和布局.显然,我用某种风格编写代码.部分原因是因为我没有选择(如果我在逗号之前错过了一个空格就不会编译),但是定期看代码,知道在哪里寻找东西等等也很好.
在周末我要进入斯卡拉.看看Scala API和Lift Web框架源代码,我无法看到任何标准化的样式.例如,跳出来的一件事是每个类缺少一个单独的文件.与括号和括号缺乏一致性是另一个例子.
我理解推动这个问题的原因可能有几个:首先,使用开源(或爱好)代码确保一个明显的方法没有完全记录,这不是一个优先事项.其次,像case类这样的东西会将20行的类声明减少为一行.第三,C#是一种非常"平坦"的语言:除非它是一个复杂的LINQ语句,嵌套的parens,括号和括号的数量并不那么深.在Scala中,事情往往会有点嵌套.
常规的Scala用户是否具有他们坚持的特定风格?为了[异化]惯例,我只是把一个单行的案例类放在自己的文件中愚蠢吗?有小费吗?
Dan*_*ral 45
在单个文件中具有多个类和对象在Scala中被认为是良好的形式,只要这些类紧密相关即可.
虽然不是必需的,但是一个方法返回的类型 - 在特征,类或对象上声明的命名函数 - 应该为非私有方法声明.预计会有空间:,但不会超过它.
// 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))
}
Run Code Online (Sandbox Code Playgroud)
预期关键字和括号之间的空格,但不是在方法名称和下面的括号之间,用点表示法.对于操作符号,似乎没有关于括号的可接受的样式 - 或者何时使用该表示法,但是在这种表示法中围绕非字母数字方法期望空格.
// keywords
if (foo) ...
// dot notation
foo.doSomething(bar)
// operator notation
foo doSomething bar
foo + bar
Run Code Online (Sandbox Code Playgroud)
特殊情况下,在连接字符串时+,建议的样式不要使用它周围的空格.例如:
// concatenate strings
println("Name: "+person.name+"\tAge: "+person.age)
Run Code Online (Sandbox Code Playgroud)
除非嵌套不明显,否则可以是单行的声明应该是单行的.
// one-liners
lazy val foo = calculateFoo
def square(x: Int) = x * x
Run Code Online (Sandbox Code Playgroud)
不期望参数且没有副作用的方法应该在没有括号的情况下使用,Java方法除外,它们应该与括号一起使用.具有副作用的无参数方法应该与括号一起使用.
// without side-effects
val x = foo.length
val y = bar.coefficient
// with side-effects
foo.reverse()
Run Code Online (Sandbox Code Playgroud)
包含单个表达式的声明不应包含在花括号内,除非其他语法注意事项使其不可能.在括号内包含表达式以启用多行表达式是可以接受的,但我看到它的用处很少.
// single-line expression
def sum(list: List[Int]): Int = if (!list.isEmpty) list reduceLeft (_ + _) else 0
// multi-line expression
val sum = (
getItems
reduceLeft (_ + _)
)
Run Code Online (Sandbox Code Playgroud)
在理解中,保持发电机和条件垂直对齐似乎是一种公认的风格.至于yield,我看到它既对齐for又缩进.
// 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)
Run Code Online (Sandbox Code Playgroud)
垂直对齐类声明的参数也是可接受的样式.
说到缩进,两个空格是公认的惯例.
预计大括号将在声明的同一行开始,并自行与该行垂直对齐.
// 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)
}
Run Code Online (Sandbox Code Playgroud)
对于过程 - 返回类型为 - 的函数Unit,期望的样式应该是省略方法的类型和等号:
// procedures
def complain {
println("Oh, no!")
}
Run Code Online (Sandbox Code Playgroud)
有些人认为这种风格容易出错,因为错过的等号会改变一个函数而不是返回Unit一个过程.
标识符是用camel case编写的(例如:) identifiersHaveHumps,就像在Java中一样.对于字段名称,方法参数,局部变量和函数,以小写字母开头.对于类,特征和类型,以大写字母开头.
离开Java约定是常量名称.在Scala中,练习是使用以大写字母开头的标准驼峰盒.例如Pi,不是PI,XOffset而不是X_OFFSET.此规则通常后跟任何单身人士.对于案例匹配,以这种方式表示常量和单例具有实际结果:
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
}
Run Code Online (Sandbox Code Playgroud)
包名称以小写字母开头.当在import语句中区分什么是包而什么不包时,这尤其有用.在前面的示例中,Math不是包(它是单例),因为它以大写字母开头.
_建议不要使用下划线字符 - - 因为该字符在Scala中有许多特殊含义.这些标识符规则可以在Odersky,Spoon&Venners的Scala编程的第141和142页找到.
现在,我不记得其他情况,但随时可以要求澄清具体要点.其中一些规则已明确说明,其他则更多是社区共识.我试图忽略自己的偏好,但我可能失败了.
更重要的是,或许,实际上并没有太多统一的惯例.其中一个原因可能是Scala吸引了许多不同背景的人,例如功能语言专家,Java程序员和Web 2.0爱好者.
| 归档时间: |
|
| 查看次数: |
5191 次 |
| 最近记录: |