Scala

**Scala**（發音為 /ˈskɑːlə, ˈskeɪlə/）是一門多範式的程式語言，設計初衷是要整合物件導向程式設計和函式語言程式設計的各種特性。

## 平台和授權條款

Scala 執行於 Java 平台（Java 虛擬機器），併兼容現有的 Java 程式。它也能執行於 CLDC 組態的 Java ME 中。曾經有過另一.NET 平台的實現，不過該版本已被放棄。

Scala 的編譯模型（獨立編譯，動態類載入）與 Java 和 C# 一樣，所以 Scala 代碼可以呼叫 Java 類別庫（對於.NET 實現則可呼叫.NET 類別館）。

Scala 套件包括編譯器和類別館，以 BSD 授權條款釋出。

## 歷史

洛桑聯邦理工學院的 Martin Odersky 於 2001 年基於 Funnel 的工作開始設計 Scala。Funnel 是把函式語言程式設計思想和佩特里網相結合的一種程式語言。 Odersky 之前工作於 Java 泛型和 javac。Java 平台的 Scala 於 2003 年底 / 2004 年初釋出。.NET 平台的 Scala 釋出於 2004 年 6 月。該語言第二個版本，v2.0，釋出於 2006 年 3 月。

Scala 2.8 的特性包括重寫的 Scala 容器庫、命名參數和預設參數、套件物件，以及 Continuation.

2012 年 1 月，釋出版本 2.9.1。

2012 年 4 月，釋出版本 2.9.2。

## 使用 Scala 的軟體

* 2009 年 4 月，Twitter 宣布他們已經把大部分後端程式從 Ruby 遷移到 Scala，其餘部分也打算要遷移。
* Wattzon 已經公開宣稱，其整個平台都已經是基於 Scala 基礎設施編寫的。
* 瑞銀集團把 Scala 用於一般產品中。
* Coursera 把 Scala 作為伺服器語言使用。
* 多鄰國，一個線上的免費語言學習平台，使用 Scala 編寫。

## 特性

### 支援的編程範式

#### 物件導向特性

Scala 是一種純物件導向的語言，每個值都是物件。物件的資料類型以及行為由類別和特質描述。類抽象機制的擴充有兩種途徑。一種途徑是子類繼承，另一種途徑是靈活的混入機制。這兩種途徑能避免多重繼承的種種問題。

#### 函式語言程式設計

Scala 也是一種函數式語言，其函式也能當成值來使用。Scala 提供了輕量級的語法用以定義匿名函式，支援高階函式，允許巢狀多層函式，並支援柯里化。Scala 的 **case class** 及其內建的模式匹配相當於函式語言程式設計語言中常用的代數型別。

更進一步，程式設計師可以利用 Scala 的模式匹配，編寫類似正規表示式的代碼處理 XML 資料。在這些情形中，列表推導式功能對編寫公式化查詢非常有用。

由於 JVM 不支援尾呼叫，Scala 也不能完全支援尾呼叫最佳化。不過，Scala 編譯器可以把某些簡單的尾遞迴最佳化成迴圈。

以下代碼以函數式風格實現了快速排序演算法，可以與 Erlang 快速排序的例子做個比較：

### 靜態型別

Scala 具備型別系統，通過編譯時檢查，保證代碼的安全性和一致性。型別系統具體支援以下特性：

* 泛型類別，
* 協變和逆變，
* 標註，
* 型別參數的上下限約束，
* 把類別和抽象型別作為物件成員，
* 複合型別，
* 參照自己時顯式指定型別，
* 視圖，
* 多型方法。

### 擴充性

Scala 的設計秉承一項事實，即在實踐中，某個領域特定的應用程式開發往往需要特定於該領域的語言擴充。Scala 提供了許多獨特的語言機制，可以以庫的形式輕易無縫添加新的語言結構：

* 任何方法可用作字首或字尾運算子，
* 可以根據預期型別自動構造閉包。

聯合使用以上兩個特性，使你可以定義新的語句而無須擴充語法也無須使用宏之類的元程式設計特性。

### 並行性

Scala 使用演員模型作為其並行模型，Actor 是類似執行緒的實體，通過電子信箱發收訊息。Actor 可以復用執行緒，因此可以在程式中可以使用數百萬個 Actor, 而執行緒只能建立數千個。在 2.10 之後的版本中，使用 Akka 作為其預設 Actor 實現。
以下代碼是使用 Actor 模式的 EchoServer 實現

Actor 模式可以簡化並行編程，好利用多核 CPU 的能力。

## 使用 Scala 的框架

Lift 是開源的 Web 應用框架，旨在提供類似 Ruby on Rails 的東西。因為 Lift 使用了 Scala，所以 Lift 應用程式可以使用目前所有的 Java 庫和 Web 容器。

## Hello World 範例

以下是用 Scala 編寫的典型 Hello World 程式：

或

請注意它與 Java 的 Hello World 應用程式有哪些相似之處。一處顯著區別在於，Scala 版的 Hello World 程式不通過 **static** 關鍵字把 **main** 方法標記為靜態方法，而是用 **object** 關鍵字建立了單件。

假設該程式儲存為 HelloWorld.scala 檔案，接下來可以通過以下命令列進行編譯：

```
> scalac HelloWorld.scala
```

若要執行：

```
> scala -classpath . HelloWorld
```

這與編譯和執行 Java 的「Hello World」程式是不是很像呢？事實上，Scala 的編譯和執行模型與 Java 是等效的，因而它也相容於 Java 的構建工具，比如 Ant.

直接使用 Scala 直譯器也可以執行該程式，使用選項**-i**（從檔案載入代碼）和選項**-e**（若要執行額外的代碼，就得實際執行 HelloWorld 物件的方法）即可：

```
> scala -i HelloWorld.scala -e 'HelloWorld.main(null)'
```

## 測試

以下是測試 Scala 代碼的一些方式：

* ScalaTest（頁面存檔備份，存於網際網路檔案館）
* ScalaCheck（頁面存檔備份，存於網際網路檔案館），類似於 Haskell 的 QuickCheck（頁面存檔備份，存於網際網路檔案館）的庫
* specs（頁面存檔備份，存於網際網路檔案館），用於 Scala 的行為驅動的開發工具庫
* JUnit

內建的 Scala 庫 **SUnit** 已經不贊成使用，已在 2.8.0 版中移除。

## 參考文獻

## 圖書

* Programming in Scala（頁面存檔備份，存於網際網路檔案館）(ISBN 978-0-9815316-0-1) - A comprehensive step-by-step guide by Martin Odersky, Lex Spoon, and Bill Venners.
* Beginning Scala(ISBN 978-1-4302-1989-7) - A down–to–earth approach to teaching Scala by David Pollak.
* Programming Scala(ISBN 978-1-934356-31-9) - Creating highly scalable, highly concurrent applications on the Java platform by Venkat Subramaniam.
* Programming Scala (ebook)（頁面存檔備份，存於網際網路檔案館）

## 外部連結

* Scala website（頁面存檔備份，存於網際網路檔案館）
* Scalachina（頁面存檔備份，存於網際網路檔案館）
* Scala Tour, 開源 Scala 指南
* Scala 教學（頁面存檔備份，存於網際網路檔案館）