Ruby高手点评Scala编程语言

<转载>

◆Scala 的确很棒。

◆我的确认为计算机学院应该开一门 Scala 的语言课程。

在这篇文章中,我会讲述为什么我会有这样的想法,在此之前,有几点我想要先声明一下:

本文无意对编程语言进行评比,我要讲述的主体是为什么你应该学习 Scala。51CTO之前曾发布过一篇 Java 程序员为何要学习Scala的文章,可能也会对你有所帮助。

目前 Scala 有两个实现方式,一种是在 JVM(Java 虚拟机)上运行,另一种是在 CLR(Common Language Runtime 的缩写,即公共语言运行库)上运行。不过,JVM 的实现方式更为成熟。如果你想要使用 .Net framework 框架,我认为最好还是听从 Lift framework 框架创始人大卫波拉克(David Pollack)的建议:使用 F#。但在这篇文章中,我将只关注 JVM 这种实现方式。

我是一个 Ruby 程序员,并且我会继续喜欢 Ruby,因为它是我见到过的最棒的动态语言。但我也喜欢 Scala,因为在其他工作领域,它提供的某些功能非常强大。

现在,让我们来仔细分析一下,是哪些原因让我选择 Scala 作为我的下一个编程语言:

强大的编程语言

Scala 是一门非常强大的语言,它允许用户使用命令和函数范式进行编写代码,因此,编程时你可以使用常用的命令式语句,就像我们使用 C、Java、PHP 以及很多其他语言一样,而且,你也可以使用类似 Lisp 语言中函数式语句,还有,你可以混合使用这两种风格的语句,就像 Ruby 或 Groovy。

不过,当我们谈论的函数范式时,与 Ruby 和 Groovy 有一点不同的地方,那就是 Scala 几乎支持函数语言中所有已知的功能,比如,模式匹配(Pattern matching)、延迟初始化(Lazy initialization)、偏函数(Partial Function)、不变性(Immutability),等等...即是说,认识到这样一个事实是非常重要的:Scala 的强大源自它对函数范式的支持,而后者令 Scala 成为一种高等级(high-level)的编程语言。对于高等级的编程语言,你只需关注 what(做什么)而不是如何做(how)。

下面,让我们看一个 Java 示例:

int[] x = {1,2,3,4,5,6}; ArrayList res = new ArrayList(); for (int v : x) { if (v % 2 == 1) res.add(new Integer(v)); }

仔细看一下上面这段示例代码,你会注意到,我想要做的“what”部分(过滤掉奇数值)仅出现在第四行中,而其余行则是“how”如何做的部分(结果变量的初始化以及一个循环操作)。如果我想要再写一个过滤器,用于筛选偶数值,那就需要再写五行代码,而使用一门像 Scala 这样的高等级语言,你只需编写“what”那部分的代码:

val x = Array(1,2,3,4,5,6) val res = x filter ( _ % 2 == 1 ) //过滤奇数值 val res2 = x filter ( _ % 2 == 0 ) //过滤偶数值

我们可以看到,相对于上文中的 Java 代码段,这段代码更加简洁,而且具有更好的可读性。

高效

Scala 是一种高效的编程语言,实际上,根据最新的 benchmark 性能测试,它几乎和 Java 一样快捷。在 JVM 上实现的 Scala 代码,可以编译为字节码,在这一过程中,代码通过优化阶段进行编译。尾递归优化是一个很好的示例,它可帮助用户专注于函数范式而无需以牺牲性能为代价。还有一个示例是,将 Scala 值类型对象转换为 Java 基本类型时进行的优化。

可扩展

Scala 语言本身的名字 Scala 来自 Scalable(可扩展的)一词,这意味着这种语言可以按照用户的需求进行扩展。因此,从根本上来讲,用户可以添加新的类型和控制结构。比如,我想要添加一个简单的“loop”控制结构:

// 一个简单的构建 def loop(range: Range)(op: Int=> Unit) { range foreach (op) } loop(1 to 5){println} // 1 2 3 4 5 loop(1 to 5){x => if (x % 2 == 0) println(x)} // 2 4

还有几个更为复杂的例子,Actor lib,它是作为扩展被添加到 Scala 这一语言中的,我们将在下文中对它展开讨论。

不过,Scala 之所以是可扩展的,在于互相关联的两点:它是真正的面向对象的语言和真正的函数式语言。

面向对象

Scala 中每个事物都是对象(对象的方法除外),因此,没有必要对基本(primitive)类型或引用类型进行区分,这就是所谓的:统一对象模型(Uniform Object Model)。但是,正如我之前在优化流程中所提到的,值类型对象被转换为 Java 基本类型,因此不必担心性能的问题。其内部还包含为类方法分组的单件对象(Singleton object)。

◆所有操作都是方法调用,+ - * ! / 都是方法,因此,没有必要进行操作符重载。

◆非常精细的访问控制,用户可以控制对某些包的某些方法的访问。

◆Scala 具有 trait,与 Ruby 中的 mixin 类似,就像 Java 中的 interfaces,但实现了某些它们的方法,因此,用户在箱体(box)之外拥有富封装器(wrapper)和富交互接口(interface)。

函数式语言

函数式语言具有很多特点,不过在扩展性这一语境中,我们所关心的是两个事实:

◆函数是第一等级(first-class)的值

这表示用户可以将函数作为值传递,也可以作为值返回。这样可以获得简洁而具有可读性的代码,正如上文中作为示例的过滤代码段。

◆纯函数(pure function)

Scala 支持没有副作用的纯函数,这意味着:如果你的输入相同,那么输出结果也总是相同。这样能够让代码更为安全,对代码测试也更为方便。

但是,Scala 是通过什么方式来支持纯函数的呢?通过不变性(immutability):偏向固定的引用(与 java 中的 final 或其他语言中的 constant 类似)以及具有不变的数据结构,一旦创建便不可修改。

不变性是拥有纯函数的安全保证,但并不是唯一的方式。没有不变性,你仍然可以编写安全的代码。这就是为什么 Scala 不是强制推行不变性而只是鼓励使用它。最终,你会发现 Scala 中许多数据结构具有了两种实现方式,一种是可变的,另一种是不可变的,不可变的数据结构是缺省导入的。

每当提到不变性时,有人就会开始担心性能的问题,对于某些情况,这种担忧并非毫无来由,但对于 Scala,最终结果却与这一担忧相反。不可变的数据结构相对于可变的数据结构,更有助于获得较高的效率。其原因之一在于强大的垃圾收集器(garbage collector),与 JVM 中的垃圾收集器类似。

更佳的并行模型

当涉及到线程这一问题时,Scala 支持传统的 shared data 模型。但是,使用这种模型较长一段时间之后,许多人发现使用这种模型编写代码,非常难以实现以及进行测试。你总是需要考虑死锁问题和竞争条件。因此,Scala 提供了另一个称为 Actor 的并行模型,其中,actor 通过它的收件箱来发送和接收非同步信息,而不是共享数据。这种方式被称为:shared nothing 模型。一旦你不再顾虑共享数据的问题,也就不必再为代码同步和死锁问题而头痛。

被发送信息的不变性本质以及 actor 中串行处理,这两者使得对于并行的支持更为简便。

有关 Scala 并行的问题,请参阅这篇文章,对于这个概念你会有更好的理解。

在讲述下一个要点之前,我需要提到这样一个事实,一些人将 Actor 的使用视为编程语言的一种进化。正如,Java 的出现,将程序员们从指针和内存管理的泥淖中拯救出来一样,Scala 的到来,让程序员们不必再为代码同步以及共享数据模型整天苦思冥想。



____________________________________________________________________________________________



Scala技术交流群27870655,欢迎您的加入!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值