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 关键字

reference: http://www.scala-lang.org/

Comments

求教

那个, 我是在搜索一个scala的相关问题的时候找到您这个网站的, 搜搜看看, 感觉好多东西都是自己曾今或是近期或是现在感兴趣的和正在学习的东西,SOA, OSGi, BlazeDS(也许包括FLEX?),还有就是scala, 这些东西都能激起我很大的兴趣,但是因为各种原因,都是在学习一段时间之后荒废了,也不能说荒废了,就是不能继续全身心地投入学习了,由于我正处在从学校到社会寻找工作的关键阶段(也就是我现在马上升大四了),我现在特别困惑,我现在实习的地方要求我做的东西几乎都是自己曾今不曾关注的东西,简单点就是我一直钻研java,而我现在完全使用c进行开发。。比较郁积和苦恼。对摆在自己面前的路实在是很困惑,特此求教,如何在工作之后保持对自己兴趣的追求。(我现在由于对整个软件行业的接触还不算多, 接触的软件公司也较少,所以更是迷茫。 ps:我是北京某高校2011届应届。。)
真心希望能解答一二。

说说我一直的想法

工作和爱好能兼得当然好了,不能兼得就坚持自己喜欢的。
当然对工作还是要一丝不苟,干什么都必须先做好应该做的。
Java和C 其实做时间长了会对个人的技术方向有一定影响,一般做Java 的都喜欢往架构上靠,往往忽略算法之类的基础问题;C呢往往会往细节钻进去,会对每种技术细节了解的非常清楚。
看你自己喜欢了。
上学的时候真的是非常宝贵的。有大把的时间可以专心学习,希望你不要荒废,祝你成功!

julian0zzx

嗯,其实要坚持还是要付出点代价,毕竟要讨生活,不过慢慢发现

嗯,其实要坚持还是要付出点代价,毕竟要讨生活,不过慢慢发现C也挺有意思的,确实之前关注整体的架构多过算法的方面,应该还不晚。想要兼顾估计是不太可能,但是我感觉看的东西多了看问题的角度会不一样。我一直相信兴趣是最好的导师,有人交流感觉很好,谢谢了。。

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.