Scala是什么
Scala语言的名称来自于“可伸展的语言”。
之所以这样命名,是由于他被设计成随着使用者的需求而成长。你能够把Scala应用在非常大范围的编程任务上。从写个小脚本到建立个大系统。
51CTO编辑推荐:Scala编程语言专题
Scala是非常easy进入的语言。
它跑在标准的Java平台上。可以与全部的Java库实现无缝交互。
它也是用来编写脚本把Java控件链在一起的非常好的语言。可是用它来建立大系统和可重用控件的架构将更可以发挥它的力量。
从技术层面上来说,Scala是一种把面向对象和函数式编程理念增加到静态类型语言中的混血儿。Scala的很多不同的方面都展现了面向对象和函数式编程的熔合;也许它比其它那些广泛使用的语言更有渗透性。在可伸展性方面。这两种编程风格具有互补的力量。
Scala的函数式编程使得它便于高速地从简单的碎片開始建立一些有趣的东西。
它的面向对象特性又使它便于构造大型系统并使它们适应于新的需求。
Scala中这两种风格的组合使得它有可能表达新的编程模式和控件抽象。并产生了易读、简洁的编程风格。因为它良好的延展性,用Scala编程将会有非常多的乐趣。
不同尺寸的程序倾向于须要不同的编程结构。
举例来说。考虑下面的Scala程序:
- var capital = Map("US"->"Washington", "France" -> "Paris")
- capital += ("Japan" -> "Tokyo")
- println(capital("France"))
这段程序建立了一个国家和它们的首都之间的映射表,添加了一个新的绑定("Japan"->"Tokyo")。然后打印了与法国相关的首都。
本例中的声明都是高层次的。也就是说。没有被外加的分号或者类型凝视弄得乱糟糟的。实际上,这样的感觉就好像那种现代的“脚本化”语言,比方。Perl,Python或者Ruby。这些语言的一个普遍特征,与上例有关的,就是它们都在语法层面上支持“关联映射”。
关联映射很实用,由于它能让程序易读和清晰。然而。有些时候你也许不赞成它们的这样的“均码”哲学,由于你须要用一种更加细粒度地去控制在你程序中用到的映射的属性。Scala能够在你须要的时候提供这样的细粒度的控制。由于映射在Scala里并非语法特性。
它们是库抽象,你能够扩展或者改造。
在上面的程序里。你将获得一个缺省的Map实现,只是你也能够非常轻松地改变它。例如说,你能够定义个特别的实现,如HashMap或TreeMap,或者你能够特定这个映射必须是线程安全的,混入:mix-in个SynchronizedMap特色:trait。你还能够给映射特定一个缺省值,或你能够重载你创建的映射的随意方法。每一个样例里,你都能够如上例所看到的那样使用相同简单的映射訪问语法。
这个样例显示了Scala带给你的方便性和灵活性,能够让你更好的了解Scala是什么。Scala有一整套的方便构件来帮助你高速启动及让你用一种愉悦清晰的状态编程。
与此同一时候。你有信心你不会让语言过度发育。
你总能够把程序按你的须要裁剪。由于全部的东西都是基于库模块的。能够按照须要选择和改动。
Scala是什么:培育新的类型
Eric Raymond把大教堂和杂货铺作为软件开发的两个隐喻。 大教堂是几近于完美的建筑物,要花非常长的时间建设。一旦建成了,就长时间保持不变。
相对来说,杂货铺则天天在被工作当中的人调整和扩展。
Raymond的文章中,杂货铺是对于开源软件开发的隐喻。
Guy Steele在他的讲话“发展一门语言”中提到相同的区别也能够应用在语言定义中。 Scala更像一个杂货铺而不是大教堂,由于它被设计为让用它编程的人扩展和改动的。
Scala并没有提供全部你在一种“完美齐全”语言中可能须要的东西,而是把制作这些东西的工具放在了你的手中。
这儿有个样例。
很多程序须要一个可以变得随意大都不会溢出或者因为数学操作而“绕回”的整数类型。
Scala在库类Scala.BigInt中定义了这样一个类型。
这里有一个使用了那个类型的方法定义。用以计算传入整数的阶乘值:
- def factorial(x: BigInt): BigInt =
- if (x == 0) 1 else x * factorial(x - 1)
如今,假设你调用了factorial(30),你将得到:
265252859812191058636308480000000
BigInt看上去就像一个内建的类型,由于你能够使用整数值和这样的类型值的操作符如*和-。
然而它仅仅是凑巧定义在Scala标准库中的类。
假设这个类缺失了,能够直接由随意的Scala程序猿写一个实现出来,举例来说,通过包装Java的类java.math.BigInteger(实际上,Scala的BigInt就是这么实现的)。
当然。你也能够直接使用Java的类库。
但结果却不尽乐观,由于虽然Java同意创建新的类,但这些类总感觉不像原生的语言支持。
- import java.math.BigInteger
- def factorial(x:BigInteger): BigInteger =
- if (x == BigInteger.ZERO)
- BigInteger.ONE
- else
- x.multiply(factorial(x.subtract(BigInteger.ONE)))
BigInt代表了更多类似于数字的类型——大十进制数,复数,分数。置信区间,多项式——诸如此类。一些编程语言原生实现了当中的一些类型。举例来说。Lisp,Haskell和Python实现了大整数。Fortran和Python实现了复数。可是不论什么语言想要尝试同一时候实现全部的这些抽象类型将非常easy变得太大而难以管理。
更进一步,即使假设有这种语言,总有些应用会使用其它的没支持的数字类型。所以尝试在一种语言里提供全部东西的解决之道不可能非常好地伸展。
取而代之。Scala同意用户在他们须要的方向上通过定义易用库来发展和改造语言,使得这些特性感觉上好像原生语言支持一样。
培育新的控制结构
前面的样例演示了Scala让你添加新的类型。使得它们用起来方便得像内建类型一样。相同的扩展理念也应用在控制结构上。
这样的类型的扩展是由Scala的“基于行动类”的并发编程API阐明的。
随着近年多核处理器的激增。为了获取可接受的性能,你将必须在应用中运用很多其它的并行机制。经常这就意味着重写你的代码来让计算分布到若干并发线程上。不幸的是,创建依赖性的多线程程序在实践中被证明是非常具有挑战性的。Java的线程模型是环绕着共享内存和锁建立的。尤其是当系统在大小和复杂度都得到提升的时候。这样的模型经常是不可理喻的。
非常难说程序里面没有资源竞争或潜藏的死锁——有些东西不是能在測试里面检验得出,而也许仅仅在投入生产后才表现出来。而大致能够觉得比較安全的可选方案是消息传递架构。比如在Erlang编程语言中应用的“行动类”方案。
Java伴随着一个丰富的,基于线程的并发库。Scala能够像其它JavaAPI那样使用它编程。然而,Scala也提供了一个实质上实现了Erlang的行动类模型的附加库。
行动类是可以实现于线程之上的并发抽象。
它们通过在彼此间发送消息实现通信。每一个行动类都能实现两个基本操作,消息的发送和接受。发送操作,用一个惊叹号表示,发送消息给一个行动类。这里用一个命名为recipient的行动类举比例如以下:
- recipient ! msg
发送是异步的;就是说。发送的行动类能够在一瞬间完毕,而不须要等待消息被接受和处理。
每个行动类都有一个信箱:mailbox把进入的消息排成队列。
行动类通过receive代码块处理信箱中受到的消息:
- receive {
- case Msg1 => ... // handle Msg1
- case Msg2 => ... // handle Msg2
- // ...
- }
接收代码块由很多case语句组成,每个都用一个消息模板查询信箱。信箱中第一个符合不论什么case的消息被选中,而且运行对应的动作。
假设信箱中不含有不论什么符合不论什么case的消息,行动类将休眠等待新进的消息。
这里举一个简单的Scala行动类实现检查值(cheksum)计算器服务的样例:
- actor {
- var sum = 0
- loop {
- receive {
- case Data(bytes) => sum += hash(bytes)
- case GetSum(requester) => requester ! sum
- }
- }
- }
这个行动类首先定义了一个名为sum的本地变量。并赋了初值为零。然后就用receive段落反复等待在消息循环中。假设收到了Data消息,就把发送的bytes取哈希值加到sum变量中。假设收到了GetSum消息。就用消息发送requester!sum把当前sum值发回给requester。requester字段嵌入在GetSum消息里;它通常指出创建请求的行动类。
眼下我们并不指望你能全然明确行动类样例。
实际上,对于可伸展性这个话题来说这个样例里面最重要的是,不论是actor还是loop还是receive还是发送消息的符号“!”,这些都不是Scala内建的操作符。虽然actor,loop和receive看上去或者表现上都如此接近于控制结构如while或者for循环,实际上它们是定义在Scala的行动类库里面的方法。相同,虽然“!”看上去像是个内建的操作符。它也只是是定义在行动类库里面的方法。全部这四个构件都是全然独立于Scala语言的。
receive代码块和发送“!”语法让Scala看上去更像Erlang里的样子,可是在Erlang里面,这些构件是内建在语言中的。Scala还实现了Erlang其它并发编程构件的大多数,诸如监控失败行动类和超时类。总体来说,行动类已变成表达并发和分布式计算的很好的办法。
虽然它们是定义在库里的,给人的感觉就像行动类是Scala语言总体的部分。
本例演示了你能够向新的方向“培养”Scala语言乃至像并发编程这种特性。前提是,你须要一个好的架构和程序猿来做这种事。但重要的事情是这的确可行——你能够在Scala里面设计和实现抽象结构,从而高速投入新的应用领域,却仍然感觉像是原生的语言支持。
本文节选自Martin Odersky,Lex Spoon和Bill Venners所著,Regular翻译的《Programming in Scala》的第一章。
本文借鉴于http://developer.51cto.com/art/200907/134865.htm