Scala flexible syntax: bad or good
Scala flexible syntax: bad or good?
Scala 风格太多变了,做一件事可以有N 条路。
比如声明一个方法:
val multiply = (x:Int) => x * x
def multiply(x : Int) : Int = {
return x * x;
}
这方法都可以用multiply(3) 来调用。当然你完全可以说前一种是把匿名方法赋值给常量multiply。但是在我看来,这只是修辞上的问题,对结果并无影响。如果说上面这种还有说辞,那请看下面的代码:
val aaa = 1 to 3 val bbb = 1.to(3)
这两种形式是完全等价的,只是在写法上有区别而已。
在语句分割上Scala 也采取了比较灵活的方式,一行是一条语句,如果想把两条语句放在同一行,可以用分号分隔。上面的常量声明可以像下面一样写在一行:
val aaa = 1 to 3; val bbb = 1.to(3);
当然即使分开写成两行,也可以把分号用作一条语句的结束。
上面只是最基本的两点,还有其他的一些诡异的地方。老实说这很大程度上是因为我对Scala 还不是那么熟悉,以致我在刚开始摸Scala 的时候无所适从,嗯,其实刚开始摸什么都是一样-_-!
只有一个参数的方法调可以用 object method argument 的方式,Python 也有类似的情形。不过对Scala,我采用了对待Python 同样的方式,直接忘记这种写法,只记得object.method(argument),毕竟这和多个参数的写法一致。
还有一处乍看起来很迷惑,但是如果糊里糊涂起来却很自然的地方,Scala 的类型推断。大部分的强类型语言中,我们都习惯于先声明变量的类型,然后再进行操作,像继承自C 的编程语言,基本都是这个路子。弱类型语言不是这样的,弱类型基本是采用了推断的方式,即看变量被赋予了什么样的值。比如看下面的循环:
for ( i <- 1 to 2 ) {
println( "No." + i )
}
变量i 并没有指定是何类型, 但是完全可以通过1、2 来推定是Int 。 很自然不是吗?
使用Scala,既可以写命令式的代码,也可以写函数式的代码。命令式的代码就不用说了,C家族的语言到现在基本都是命令式的。函数式的代码可以把函数作为方法传到函数内,下面是个简单的例子:
val sqr = (ss : String, x : Int) => ss + x * x;
def call(f : ((String, Int) => String), s : String, n : Int) : String = {
f(s, n);
}
// sqr is a function
println(call(sqr, "3*3=", 3));
这个例子很简单,就是定义了一个方法,然后作为另一个方法的参数来调用。这个方法只能示例函数式大概的样子,函数编程的强大完全体现不出来。函数式编程最大的特点应该是每个变量只能初始化一次,一旦初始化之后就再也不能改变它的值,在Scala 中这样的变量用val 来定义。下面是另一个稍微复杂点的例子:
val nn = (0 to 10); val whatisthis = nn.reverse.map(e => e + 10).foreach(x => print(x + ",")); println(); // just for a new line nn.foreach(e => print(e + ","));
输出结果是:
20,19,18,17,16,15,14,13,12,11,10, 0,1,2,3,4,5,6,7,8,9,10,
稍微解释一下,nn 的类型为scala.collection.immutable.Range。这里,我们先把集合反转,再把每个元素加10,回头坚持最开始的nn,却发现没有改变。(whatisthis 什么都不是)
函数式的编程语言可以写出非常强大,但是短小精悍的代码,当然前提是习惯了函数式的思路。
Scala 是一门溶命令式和函数式为一身的编程语言。这当然是一个优势,熟悉命令式或者函数式编程方法的兄弟,都可以充分利用Scala 强大的库。但是对新手来说,如果陷入对两种编程方式的艰难选择而不能自拔,那么Scala的这种优势基本上就变成了一个灾难。所以,我强烈不建议新手们把Scala 用到生产环境中。只有对Scala 非常熟悉,能够熟练的应用两种思路最直接地解决问题,这时候才能真正把Scala 用于生产。毋庸置疑的,Scala 生产力非常强大,绝对值得投资。(非广告)
在使用Scala 时有这么多可用的方法可以选择,改如何是好呢?其实每种方法都有她的优点,不能说哪种是最好的,因为每个人看法不一定一样,而且不同的方式在特定的情况下可能分别都是最优方案。就我个人来讲,我倾向于在一份代码中采用相同的编码方式。在多人(甚至只要超过两个人)团队中,代码风格泛滥一定会成为障碍,尤其是对新加入团队的成员来说。在我的团队中,我会要求以下几点:
0/ 要么命令式、要么函数式,只能有一个主流,另一个严格限制在很小范围内
1/ 用大括号分割代码段,光凭换行不能充分利用文本编辑器
2/ 用分号结束语句
3/ 只有在非常明显的地方才省略类型声明,比如前面for 的例子
4/ 不用object method argument 这种方式,统一函数调用方式
5/ 变量统一用val 声明
6/ 不省略函数返回的return 关键字
Recent Comments
- Ken on SLF4J MDC and Marker
- Ken on SLF4J MDC and Marker
Archives
- February 2012 (1)
- December 2011 (1)
- August 2011 (1)
- April 2011 (1)
- March 2011 (1)
- January 2011 (14)







