1.4.1 静态类型才是正确的道路

综上所述,Scala仍然是一种静态类型语言。 但如果你仔细观察了前一节的示例,你可能已经发现,Scala的静态类型好像并没有出现在你面前,它更像是一种动态类型语言。 但是,我们为什么还要关心静态类型呢?

定义 静态类型(static typing)是一种值和变量都必须有类型的类型系统。一个数字类型的变量只能保存数字。类型必须在编译时或声明时被确定。

定义 动态类型(Dynamic typing)是一种值有类型,而变量不必有类型的类型系统。可以将一个数字和一个字符串赋给同一变量。

我们所构建的软件的量级和复杂性日益增长,拥有一个能进行类型检测的编译器是非常有意义的。 它能减少你花费在调试类型错误上的时间。 在使用静态类型语言时,比如Scala,如果你试图在一个数字对象上调用一个长度方法,Scala编译器会抛出一个编译错误。 而如果使用动态类型语言,你将得到的是一个运行时错误。

静态语言的另一个好处是它允许你使用强大的重构和IDE等工具。 也许你对IDE并不感兴趣,因为Emacs和TextMate等编辑器已足够强大,但如果拥有重构支持,尤其是工作在大型代码库上的话,将是在非常棒的一件事情。

所有的好处都是有代价的。 与动态类型语言相比,静态类型语言有更多的限制,其中一些会迫使你在声明或调用函数时必须提供额外的类型信息。 但当构建大型应用时,有限制也是好事,因为这些限制会限定一些访问代码库的规则。 Scala,做为一种类型推断(type-inferred)语言,为程序员包办了大部分样板代码(这就是编译器的好处,对吗?),让你用接近动态类型语言的使用方式,享受静态类型语言的好处。

定义 类型推断(Type inference)是一种不需要程序员提供帮助,由编译器自己来确定变量或函数的类型的技术。 编译器可以从s=”hello”中推荐出变量s是字符串类型,这是因为”hello”是一个字符串。 类型推断保证了不会有任何运行时类型错误,从而为程序员卸下了类型声明的负担。

为了展示类型推断是如何工作的,下面用Scala创建一个map类型的array:

  1. val computers = Array(
  2. Map("name" -> "Macbook", "color" -> "white"),
  3. Map("name" -> "HP Pavillion", "color" -> "black")
  4. )

如果在Scala REPL中运行这段Scala代码,你将会看到如下输出:

  1. computers:
  2. Array[scala.collection.immutable.Map[java.lang.String,java.lang.String]]
  3. = Array(Map(name -> Macbook, color -> white), Map(name -> HP Pavillion,
  4. color -> black))

虽然你只是指定了array中map的键和值,Scala编译器已经能够智能的推断出array和map的类型。 最爽的部分在于,假如你现在试图在代码库中为name分配一些整数类型的变量,编译器会抛出类型不匹配错误,告诉你不能向一个String类型变量分配一个整数。

链接