Scala语言编程入门指南

2012-11-12
    第一章 从0分到60分:Scala 介绍
    为什么选用 Scala
    当今的企业和互联网应用程序必须平衡一系列的要点。它们要有快速而可靠的实现。新的功能要能在短时间内通过周期渐进的方式加入。除了简单地提供商务逻辑之外,应用程序必须支持访问安全控制,数据持久化,事务,和其它的进阶功能。程序必须高度易用和可扩展,同时要求支持并发和分布式计算。应用程序会被网络化,并且提供人和机器都易于使用的接口。
    要达成这些挑战,许多软件开发者在寻找新型的编程序言和工具。以往备受推崇的如:Java,C#,和C++ 已经不再是开发这些次世代应用程序的最佳候选。
    如果你是一个Java 程序开发者
    Java 是由Sun 公司在1995 年,互联网高速发展的时候正式引入的。 由于当时需要一个安全的,可移植的,开发者友好的程序语言,它被迅速地推崇为编写浏览器应用的理想语言。而当时的主流语言,C++,则并不适合这个领域。
    今天,Java 被更多地使用在服务器端程序中。它是开发网络和企业应用的最流行的语言之一。
    然而,Java 是它们那个时代的产物,至今也有一定年代了。在1995年,Java 为了拉拢C++开发者,提供了和C++ 足够相似的语法,同时也避开了C++ 语言上的缺陷和危险。Java 采纳了绝大多数那个时代对解决软件开发问题有用的概念,比如面向对象编程(OOP), 同时也丢弃了一些麻烦的充满问题的技术,比如人工的内存控制。这些设计决策在最小化复杂度和最大化开发生产力上达到了一个优异的平衡。然而,从Java 出生演化到现在,许多人认为它变得越来越复杂,而且并没有显著地解决新的程序开发过程中面临的问题和挑战。
    程序开发者想要一种更精炼和更灵活的语言去提高他们的生产效率。这也是如今所谓的Ruby ,Python 这样的脚本(Script)语言大行其道的原因之一。
    永无休止的需求驱动着架构向大规模并发开发进行。然而,Java 的并发模型是基于对共享的,可变的信号状态的同步存取,从而导致了复杂的,易错的程序。
    当Java 渐渐老化时,运行它的 Java 虚拟机(JVM)却持续地散发着光芒。如今JVM 的性能优化是非凡的,它允许字节码(byte code)在许多情况下得到和本地编译的代码相同的性能。今天,许多程序开发者相信使用基于JVM 的新语言是正确的前进道路。Sun 显然是拥护这个趋势的,他们雇佣了JRuby 和Jython (Ruby 和Python 在JVM 上的实现)的主要开发者。
    Scala 的出现对于Java 开发者来说提供了一个更加新式的语言。同时保留了JVM 的惊人的性能和开发了十几年的Java 库的宝贵财富。
    如果你是一个Ruby,Python 的开发者
    像Ruby,Python,Groovy,JavaScript,和Smalltalk 这样的动态类型语言,通常因为它们优雅的灵活性,强大的元编程能力(metaprogramming),提供了很高的生产力。
    如果撇开它们在高产能上的优势,动态语言也许不是个万金油,特别对于大规模和高性能程序来说,不是最佳选择。在编程社区里,有一个对于动态类型和静态类型究竟谁更占有优势进行的冗长争论。很多的比较观点多少都有些主观。我们不会在这里讨论所有的这些争论,但是我们会提供一些对此的看法以供参考。
    相比静态语言来说,优化动态语言的性能更富有挑战性。在静态语言中,优化器可以根据类型信息来进行决策。而在动态语言中,只有很有限的信息是可用的,这使得优化器的选择更加困难。虽然近年来在动态语言优化方面的提升渐渐浮现希望,但是它们还是落在静态语言的优化艺术的后面。所以,如果你确实需要很高的性能,静态语言或许是一个更保险的选择。
    静态语言同样可以使开发过程获得好处。集成开发环境(IDE)的一些功能,比如自动完成(有时候被称为智能感知)在静态语言中更容易完成,因为那些类型信息都是可用的。而更加明显的类型信息在静态代码中促进了代码的自我解释,随着项目的发展,这对于开发者意图的互相交流是十分重要的。
    当使用一种静态语言时,你必须时刻考虑使用恰当的类型。这迫使你在选择设计时更加小心。这虽然会拖慢日常的设计决策,但是长此以往,在应用程序中对类型使用的思考会带来更为清晰的设计。
    静态语言的另外一个小的好处就是编译时期的额外检查。我们通常认为这个优势被夸大了,因为类型不匹配的错误只是日常见到的运行时错误中的一小部分。编译器无法发现逻辑错误,这显然更加重要。只有一个综合的,自动的测试组可以发现逻辑错误。对于动态语言来说,测试也必须覆盖可能的类型错误。如果你以前编写过动态类型语言,你会发现你的测试组其实会小一些,但不会小很多。
    许多开发者发现静态语言太过冗长,抱怨静态类型是冗长的元凶,而事实上真正的原因是缺少类型推断。在类型推断的情况下,编译器会根据上下文推断值的类型。例如,编译器会识别在 x = 1 + 3 中x 是一个整型。类型推断能显著地减少代码的长度,使得代码更像是用动态语言编写出来的。
    我们都曾经在不同的时间和静态语言和动态语言打过交道。我们发现两种类型的语言都因为不同的原因被广为关注。我们相信现代软件开发者必须掌握一系列的语言和工具。有时,动态语言会是完成工作的正确工具;而有时,一个静态语言,例如Scala,会是你正需要的。
    Scala 介绍
    Scala 是一种迎合现代软件开发者需求的语言。它是静态的,混合范式的(mixed-paradigm),基于JVM 的语言;它在拥有简洁,优雅,灵活的语法的同时,也提供了一个久经考验的类型系统和惯用语法,所以从小巧的解释性脚本到大型的复杂系统它都可以胜任。那可是一大口蛋糕,所以,让我们详细地来了解下它的一些特性。
    静态类型
    正如我们在前面的章节所描述的,一个静态类型的语言在一个变量的生命周期内都会绑定一个类型。相反的,动态类型的语言则是根据变量所引用的值来绑定类型,这意味着变量的类型可以随着它引用的值改变而改变。
    在最新的基于JVM 的语言中,Scala 是为数不多的静态类型语言,而且是最出名的一个。
    混合范式 - 面向对象编程
    Scala 完全支持面向对象编程(OOP)。Scala 在改进Java 对OOP 的支持的同时,添加了traits (特性)的概念,它可以简洁地实现类之间的混合关系。Scala 的traits 和Ruby 的modules (模块)概念类似。如果你是一个Java 开发者,可以把traits 想象成interfaces (接口)和implementations (实现)的统一体。
    在Scala 中,所有的东西实际上都是一个object (对象)。Scala 不像Java,它没有原始类型(元数据类型)。相反的,所有的数值类型都是正真的objects。 然而,为了优化性能,Scala 会实时地在底层实现中使用原始类型。另外,Scala 不支持static (静态)或者class-level members (类级别成员)的类型,因为它们并没有和一个实例(instance)关联。相反,Scala 支持单例模式,可以应用于那些一种类型只有一个实例的情况。
    混合范式 - 函数式编程
    Scala 完全支持函数式编程(FP)。FP 是一种比OOP 更加古老的编程范式,它被学术界的象牙塔庇护至今。FP 因为简化了某些设计,尤其是并发上的问题而受到了越来越多的关注。“纯粹”的函数式语言不允许任何易变状态(mutable state),因而避免了对易变状态的同步和共享访问。相反的,用纯函数式语言编写的程序在并发自主的进程中通过传递消息来通信。Scala 通过Actors 库来支持这种模式,但是它同时允许mutable (易变的)和immutable (不易变的)变量。
    函数是FP 的一类公民,这意味着它们可以被赋值给变量,被传递给其他函数等,就像普通的值一样。这个特色允许通过元操作来组合一些高级行为。因为Scala 遵守所有的东西都是object 的原则,函数在Scala 中也是objects。
    Scala 同时支持闭包,一种动态语言比如Python 和Ruby 从函数式编程世界中引用过来的特性。Java 很遗憾地没有在最近的版本中包含这个特性。闭包本质上是一个函数和其引用的变量的统一定义。这些变量不作为传入参数或者函数内的局部变量。一个闭包封闭了这些引用,所以函数调用可以安全的引用这些变量,即使它们已经超出了函数的作用域。闭包是一个强大的抽象,以至于objects 系统和基础控制结构经常是用它们实现的。
    一种同时有JVM 和。NET 实现的语言
    Scala 是众所周知的基于JVM 的语言,这意味着Scala 会生成JVM 字节码。一个能生成CLR 字节码的基于。NET 的Scala 版本也同时在开发中。当我们提到底层的“运行时”时,我们通常是指JVM。但是许多我们提到的概念能同时运用于两种不同的运行时。当我们讨论有关JVM 的细节时,它们大致也能应用于。NET,除非我们特别说明。
    Scala 的编译器使用了一些聪明的技巧来映射Scala 的扩展到相应的字节码。在Scala 里,我们可以轻松地调用产生自Java 源代码(JVM)或者C# 源代码(。NET)的字节码。同样的,你也可以在Java,C# 代码里调用Scala。运行在JVM 和CLR 上,允许Scala 开发者来充分利用现有的库来和运行在这些运行时的其他语言交互。
    简洁的,优雅的,灵活的语法
    Java 的语法实际上有些冗长。 Scala 使用了一些技巧来减少不必要的语法,使得Scala 源码几乎和其他的动态语言一样简洁。类型推断使得显式的类型声明信息在大多数场合下减少到了最低。类型和函数的声明变得非常简洁。
    Scala 允许函数名字包含非字母数字的字符。结合一些语法上的技巧,这些特性允许用户定义一些看起来像操作符的方法。这样,在语言核心之外的库对于用户看来就会比较自然。
    复杂的类型系统
    Scala 扩展了Java 的类型系统,同时提供了更灵活的类型和一些高级的类型结构。这个类型系统起初开起来可能会有些恐怖,但是大多数时候你不用担心这些高级的结构。类型推断帮助你自动推断类型签名,所以用户不用人工提供一般的类型信息。不过,当你需要它们的时候,高级类型特性可以给你提供更灵活的方式,用类型安全的方式解决设计上的问题。
    可伸缩性 - 架构
    Scala 被设计来服务从小的,解释性脚本到大型的,分布式系统。Scala 提供了4 种语言机制来提供更灵活的系统组合:1)显式的自我类型(selftype),2)类型成员和种类的抽象,3)嵌套的类,以及4)使用traits 的混合结构。
    没有其它的语言同时提供所有这些机制了。这些机制一起允许用一种类型安全和简洁的方式来构建由可重用组件组成的程序。正如我们所见,许多常见的设计模式和架构技术,例如依赖注入模式,可以容易地用Scala 来实现,而不用冗长的样板代码或者XML 配置文件 -- 它们经常让Java 开发变得很枯燥。
    可伸缩性 - 性能
    因为Scala 代码运行在JVM 和CLR 上,它能获得所有来自这些运行时和支持性能灵活性调整的第三方工具的性能优化,例如分析器(profiler),分布式缓存库,集群机制等。如果你相信Java 和C# 的性能,那么你就能信任Scala 的性能。当然,一些特别的结构在这个语言环境下和某些库中相比其它语言会运行地特别高效或者低效。一如既往的,你应该在必要的时候分析和优化你的代码。
    表面上看起来OOP 和FP 像是不兼容的。但实际上,Scala 的设计哲学是OOP 和FP 应该协同合作而不是对立。其中一方的特性应该能增强另一方。
    在FP 里,函数没有副作用,变量都是不易变的。而在OOP 中,可变状态和副作用都十分常见,甚至是被鼓励的。Scala 让你来选择解决设计问题最佳的方式。函数式编程对于并发特别有用,因为它摒弃了对易变状态的同步访问。然而,“纯”函数式语言是十分严格的。有一些设计问题还是使用易变对象比较容易解决。
    Scala 的名字来自词语:可伸缩的语言(scalable language)的缩写。这就建议Scala 的发音为scale-ah,实际上Scala 的创建者发音为scah-lah,像意大利语中的“stairs”(楼梯)。也就是说,两个“a 的”的发音是一样的。
    Martin Oderskey  的在计算机语言方面的背景和经验是显著的。在你学习Scala 的时候,你会了解这是一个仔细考虑了设计决策,利用了所有类型理论,OOP 和FP 的艺术的语言。Martin 在JVM 方面的经验对于Scala 和JVM 平台的优雅结合有着显著的帮助。它综合了OOP 和FP 的优点,是一个优秀的两全其美的解决方案。
    Scala 的诱惑
    今天,我们的产业幸运地拥有许多语言方面的选择。动态语言的能力,灵活性,优雅已经使它们十分流行。但是,Java 和。NET 库,已经JVM 和CLR 的性能作为珍贵的宝藏,符合了许多实际的企业和互联网项目的需求。
    Scala 引起众人的兴趣是因为它的简洁语法和类型推断,看起来像动态脚本语言。但是,Scala 提供了所有静态类型的优势,一个现代的对象模型,函数式编程,和先进的类型系统。这些工具允许你建立一个可伸缩的,模块化的应用程序,并且重用之前的Java 和。NET API, 充分利用JVM 和CLR 的性能。
    Scala 是面向专业开发者的语言。相比较与Java 和Ruby,Scala 更难掌握。因为它要求OOP,FP 和静态类型方面的技能,这样才能更高效地使用它。它诱使我们偏爱动态语言的相对简洁。但是,这种简洁是一种假象。在一种动态类型语言中,使用元编程特性来实现高级设计经常是必要的。元编程十分强大,但是使用它需要经验,而且会导致代码变得难以理解,维护和调试。在Scala 中,许多类似的设计目标可以通过类型安全的方式来达到,利用它的类型系统和通过traits 实现的混合结构。
    我们觉得在Scala 的日常使用中所需求的额外努力会迫使我们在设计时更加谨慎。久而久之,这样的几率会导致更加清晰的,模块化的,可维护的系统。幸运的是,你不必所有时候都去追逐Scala 所有复杂的功能。你的大多数代码会简单清晰,就像是用你最喜欢的动态语言写出来的一样。
    另外一个策略是联合几种简单的语言,比如Java 来做面向对象的代码,Erlang 来做函数式,并发的代码。这样一个分解会工作的很好,如果你的系统能清晰地分解成这些不想关联的部分,并且你的团队能掌控这样一个混杂的环境。Scala 对于那些仅需要一个全能语言的情况是最具吸引力的。也就是说,Scala 代码可以和谐地与其他语言共处,尤其是基于JVM 和。NET 的语言。
    安装 Scala
    这个章节描述了如何安装Scala 的命令行工具, 以便可以尽快让Scala 跑起来,这也是运行本书所有范例的必要充分条件。在各种编辑器和集成开发环境(IDE)中使用Scala 的细节,请参见和IDE 集成,在第14章-Scala 工具,库和IDE 支持。本书的范例是用Scala 版本2.7.5.final 来编写和编译, 也是本书在编写时候的最新的发行版;也有部分是用Scala 版本2.8.0 的每夜编译版本,当你读到这本书的时候应该已经最终完成了。
    注意
    2.8 版本引入了很多新的特性,我们会在这本书中予以强调。
    我们在这本书中会选用JVM 版本的Scala。 首先,你必须安装Java 1.4 或更高的版本(推荐1.5 或更高)。如果你需要安装Java,请登录,按照指示在你的电脑上安装Java。
    Scala 的官方网站 。要安装Scala,去到下载(downloads)页面 。按照下载页面上的指示下载适合你系统环境的安装包。
    最简单的跨平台安装包是IzPack 安装器。下载Scala 的jar (译注:编译完以后的Java 专属格式)文件,可以选择scala-2.7.5.final-installer.jar 或者 scala-2.8.0.N-installer.jar, N在这里是2.8.0 版本的最新发布版本。在终端窗口中(译注:或者Windwos 下的命令行),定位到下载的目录,使用java 命令来安装Scala。假设你下载了scala-2.8.0.final-installer.jar,运行如下命令会带领你完成安装过程。
    java -jar scala-2.8.0.final-installer.jar  提示
    在苹果系统下(Mac OS X),安装Scala 的最简单方式是使用MacPorts。按照这个页面的安装指示,然后使用 sudo port insall scala. 不用几分钟你就可以运行Scala 了。

    考试大温馨提示:本内容来源于网络,仅代表作者个人观点,与本站立场无关,仅供您学习交流使用。其中可能有部分文章经过多次转载而造成文章内容缺失、错误或文章作者不详等问题,请您谅解。如有侵犯您的权利,请联系我们,本站会立即予以处理。

    编辑推荐:

    统计你写的java代码行数

    JavaTimer和TimerTask详解

    8个改善Java遗留系统的技巧

分享到:
0
相关阅读
友情链接
© 2018 我考网 http://www.woexam.com 中国互联网举报中心 湘ICP备18023104号 京公网安备 11010802020116号
违法和不良信息举报:9447029@qq.com