Scala: 感觉像动态的静态语言
Weblogs Forum - Scala: The Static Language that Feels Dynamic
著名的"Thinking in Java"作者Bruce Eckel 在artima.com写了这篇Scala入门篇(banq:artima的论坛和Jdon的论坛都源于同一个宗主Jive,所以你觉得两者界面很象)。
下面大概意译一下Bruce Eckel这篇文章:
Bruce Eckel 认为scala虽然是静态语言,但感觉非常像Python,
(Bruce Eckel用语很感性,不象Thinking,而象feeling)。
|
val是不可变量,这样能够使得并发编码更容易一些(var也有变量的).这里没有必要在b之前象Java那样声明一下类型,因为scala能够分辨出类型。
|
println打印输出不必使用类似Java的System.out了,类中字段缺省是public的,这样我们可以使用b.squareFeet直接访问其类中字段。当然你也可以设置private。
|
这段和上面区别是b.feet, feet能够自动成为类的字段。
|
这段代码主要是开始的case class ,参数自动成为字段,参数之前也不用加val了。
|
scala中使用->来表示map的键和值。
|
展示了extends继承,但是注意extends后面的父类写法。
|
traits是将行为混合在一起,类似过去的AOP等,被认为用来实现DCI架构较好的语言方式,这里的trait非常类似Java中的接口,但比接口要丰富,可以自己定义方法occupants,其def是用来定义方法名称的,等于号后面是方法体。
def occupants() = { 1 }表示返回值int类型1,如果要更加规范如下:
def occupants(): Int = { 1 }
注意occupants已经成为House的一部分,这就是traits的mixin力量,而且这个mixin的性能要比Java好多。
以上是简单的语法。
函数编程方式functional programming :
比如我们有一个集合数据:
|
通过下面语法可以输出打印:
for(n <- v) {
println(n)
}
注意:<- 前面的n能够得到v集合中每个值。
还有更简单的:v.foreach(println) (Java中参数一般是变量,不会是方法等,这里是方法println)
别看这么简单,它是利用的函数编程的优点,实际是一个匿名函数,完整的基本形式:
|
=>意味着:将左边的参数应用到右边的代码中。
另外一个匿名函数案例:
(x:Int, y:Double) => x * y
之前的foreach ,实际完整的如下:
v.foreach((n:Double) => println(n))
通常情况下,scala能够看到v中的值类似是Double,因此可以简化如下:
v.foreach((n) => println(n))
如果你只有一个参数,忽略括号
v.foreach(n => println(n))
如果你只有一个参数,还可以将节省参数,用下划线替代:
v.foreach(println(_))
最后,如果函数方法只是调用一个其他方法,而且那个方法只使用一个参数,最后可以成为:
v.foreach(println)
可惜,foreach 有副作用,它不能返回任何值,大部分情况我们需要操作一个collection,并且返回值,然后,在这个返回结果上做一些操作(map/reduce),那么使用map,注意它不是数据结构Map。
v.map(n => n * 2)
将v中每个值乘以2,然后返回结果:
Vector(2.2, 4.4, 6.6, 8.8)
简写如下:
v.map(_ * 2)
还有其他操作方法:
|
v.permutations 是产生一个遍历指针iterator
v.permutations.foreach(println).
另外有用功能是zip,可以把两个集合合并在一起:
Vector(1,2,3).zip(Vector(4,5,6))
结果是:
Vector((1,4), (2,5), (3,6))
v.zip(v.map(_ * 2))结果是:
Vector((1.1,2.2), (2.2,4.4), (3.3,6.6), (4.4,8.8))
匿名函数非常简单易用,但是如果你觉得难以理解,那么可以使用标准函数:
def timesTwo(d: Double) = d * 2
v.zip(v.map(_ * 2))就变为:v.zip(v.map(timesTwo))
模式匹配
|
(banq注:在Java中大概要使用visitor模式来实现,复杂些)
match语法类似Java的switch 。但是break不是必须的。
case class对于模式匹配特别有用,因为可以分解它。Any是所有对象的根class,类似Java中的primitive类型,
Actor并发模型
这个在jdon已经讨论过多次,是一种Actor模型,通过异步消息通讯,可异步并发。要比Java多线程模型并发性能更好,彻底杜绝了共享锁。
|
(banq注:看到这段感觉很象Java的线程类,是不是可以改造一下呢)
act()方法是一个自动的 match方式,loop{ react{看上去怪,但是scala的关键,开始你能使用loop来打开邮箱消息的match状态,它实际是一个协调的多任务,每个任务做点事情然后放弃控制权,让下一个任务,这种方式好处没有共享内存,因此可以拓展伸缩,可以达数百万个任务。
注意class Benny开始两行:
this ! Hop
start()
scala不能在方法内进行对象初始化,放到方法之外,类中,!感叹号是发送消息,然后调用start()开始消息不断循环检查。
以上是Scala主要特征,本人看下来感觉是简单些,特别在了解了函数编程和Actors这两个主要编程范式和思想,我在Jdon其他帖子花过大量时间来讨论,有人感觉Scala复杂,可能是因为开始被误导?实际Scala比较简单强大。