和冗长 像我这样的动态类型语言的粉丝,认为通过鸭子类型(duck typing)可以写出更具动态性的 代码结构。但同时他们还会抱怨,静态类型语言导致代码冗长。 关于静态类型与动态类型的争论,在 51CTO 之前发布的这篇文章中可以看到更多信息。 作为静态类型语言,Scala 具有第一条中提到的优点,但是,第二点呢? Scala 具有一个灵活的类型系统,并且可能是这一类型中最好的。很多情况下,如果你没有 指定类型,这一系统将能够对类型进行推断。 例如,你可以这样编写代码: val list: List[String] = List("one", "two", "three") //list: List[String] = List(one, two, three) val s: String = "Hello World!" //s: java.lang.String = hello world! 但你也可以这样编写代码: val list = List("one", "two", "three") //list: List[String] = List(one, two, three) val s = "Hello World!" //s: java.lang.String = hello world! 非常好,无论如何,它解决了代码冗长的 问题。但像鸭子类型(duck typing)那样的问题,会怎样呢? 答案还是:Scala 的类型系统具有的某些灵活性,可以让你编写如下的代码:
def eat[T <: Animal](a: T) // whatever 其中,我们将类型 T 定义为 Animal 的子类型。还可 以更加灵活: def eat[T <: {def eat(): Unit}](a: T) // whatever 其中,我们将类型 T 定义为一个具有非法 eat 的类型。 事实上,Scala 的类型系统非常丰富,你可以在这里找到更多信息。 模式匹配 我必须坦白,在犹豫良久之后,我才决定写一写 Scala 的这一特点。事实上,我本来没有 打算讨论 Scala 的函数功能,但看到一篇有关对象分支(switch)应用的文章后,我想,还 是有必要聊聊这个特点。以下内容基本上都来自这篇博客文章: 模式匹配究竟是用来做什么的?它让你可以将一个值对多种情况(case)进行匹配,有点类 似 Java 中的分支(switch)语句。但它不是仅仅匹配数字(这是分支语句的作用) ,而是用 户能够对本质上为对象创建形式(creation form)的事物进行匹配。 以下示例也
来自上文提到的博客: x match { case Address(Name(first, last), street, city, state, zip) => println(last + ", " + zip) case _ => println("not an address") // 缺省情况 } 对于第一种情况,模式 Name(first, last) 嵌套在模式 Address(…) 中。 其中的 last 值,被传递到 Name 构造函数,然后进行提取, 因此在箭头右侧的表达式中是可用的。 那么, 模式匹配的意义 为什么你需要模式匹配?我们都会有复杂的数据。 如果我们坚持严格的面向对象编程, 那么 我们就不愿去关注数据树的内部情况。相反,我们想要调用方法,让方法来做这些事情。如 果我们有能力完成这件事,就不会非常需要模式匹配,因为方法满足了我们的要求。但是, 很多时候对象没有我们所需的方法,并且我们不能(或不愿)为对象添加新的方法。 因此,模式匹配被认为是一种获得扩张性的有效方法,并且,它还为该问题提供了一种不错 的解决方案,访问者设计模式所导致的冗长除外。 不管怎样,强烈推荐你看看上面所提到的文章中”扩展性的两个方向“ (Two directions of extensibility)那个小节。 简单的 DSL(特定领域语言) 编写 DSL,Scala 是一个很好的选择。事实上,Scala 适用于内部和外部 DSL。在这篇文 章中,你可以找到一些使用 Ruby 和 Scala 编写内部 DSL 的特点比较。下面这篇文章也
很棒,是关于使用 Scala 编写内部 DSL 的:Boolean Algebra Internal DSL in Scala (aka fun with Unicode names )。 此外,对于外部 DSL,Scala 也应该是首选语言,背后的原因是解析器组合子库(parser combinator lib) ,它让为新语言编写编译器成为一件很酷的事。 与 Java 代码之间的互操作性 在 JVM 上的实现 Scala 的程序可以无缝地与 Java 平台整合,很多 Scala 类型实际上都 编译为 Java 类型, 因此, 用户可以放心地使用 Java 类型。 而且, 你也可以混合地使用 JVM 语言来编程,如:JRuby、Groovy、Clojure 等。这里有一篇不错的文章,提供了这种示例。 学习型语言 我有两个习惯,在 Scala 的学习过程中,我坚持了这两个习惯: ◆遇到新的技术术语,访问维基百科,理解更多信息;比如 Function literal(文本函数) 、 Referentially transparent(引用透明度) 、Partial function(偏函数) 、Currying(科里华) ,还 有很多其他术语。 ◆参考我对其他语言的理解,检查这些术语的涵义是否实现。 通过一些好的练习,如编写没有副作用的纯函数,将精力集中在代码中的“what”部分,而 将“how”的部分交给语言处理;这两个习惯让我获得更多知识,也提高了代码的质量。 团队 Scala 由马丁·奥德斯基(Martin Odersky)设计,他是瑞士联邦理工洛桑分校(EPFL) 编程方法实验
室小组的管理者。奥德斯