官术网_书友最值得收藏!

1.1 一門按需伸縮的語言

不同大小的程序通常需要不同的編程概念。比如下面這段小程序:

這個程序首先設置好國家和首都之間的一組映射,然后修改映射,添加一個新的綁定("Japan" -> "Tokyo"),最后將法國(France)的首都(Paris)打印出來。[2]本例中用到的表示法高級、到位且沒有多余的分號或類型標注。的確,這段代碼看上去感覺像是一種現代的“腳本”語言,如Perl、Python或Ruby。這些語言的一個共通點,至少就上面的示例而言,是它們各自都在語法層面支持某種“關聯映射”(associative map)的結構。

關聯映射非常有用,因為它讓程序精簡可靠,不過有時你可能不同意這種“一體適用”(one size fits all)的哲學,因為你需要在你的程序中更為精細地控制映射結構的屬性。Scala給你這種自由度,因為映射在Scala里并不是語言本身的語法,它是通過類庫實現的一種抽象,可以按需進行擴展和適配。

在上面這段程序中,得到的是默認的Map實現,不過改起來也很容易。比如,可以指定一個特定的實現,如HashMapTreeMap,也可以通過調用par方法得到一個并行執行操作的ParMap。可以指定映射中的默認值,也可以在創建的映射中重寫任何方法。無論是哪一種定制,都可以復用與示例中相同的易用語法來訪問你的映射。

這個示例顯示,Scala既能讓你方便地編寫代碼,也提供了靈活度。Scala有一組方便的語法結構,可以幫助你快速上手,以愉悅而精簡的方式編程,同時,你也會很放心,因為你想實現的并不會超出語言能表達的范圍。你可以隨時根據需要裁剪自己的程序,因為一切都基于類庫模塊,任由你選用和定制。

培育新類型

Eric Raymond首先提出了大教堂和市集的隱喻,用來描述軟件開發。[3]大教堂指的是那種近乎完美的建筑,修建需要很長的時間,不過一旦建好,就很長時間不做變更。而市集則不同,每天都會有工作于其中的人們不斷地對市集進行調整和擴展。在Raymond的著作里,市集用來比喻開源軟件開發。Guy Steele在一次以“培育編程語言”為主題的演講中提到,大教堂和市集的比喻也同樣適用于編程語言的設計。[4]在這個意義上,Scala更像是市集而不是大教堂,其主要的設計目標就是讓用Scala編程的人們可以對它進行擴展和定制。

舉個例子,很多應用程序都需要一種不會溢出(overflow)或者說“從頭開始”(wrap-around)的整數。Scala正好就定義了這樣一個類型scala.math.BigInt。這里有一個使用該類型的方法,用于計算傳入整數值的階乘(factorial):[5]

現在,如果你調用factorial(30),將得到

BigInt看上去像是內建的,因為你可以使用整型字面量,并且對這個類型的值使用*-等操作符運算。但實際上它不過碰巧是Scala標準類庫里定義的一個類而已。[6]就算沒有提供這個類,Scala程序員也可以直接(比如,對java.math.BigInteger做一下包裝)實現。實際上,Scala的BigInt就是這么做的。

當然,也可以直接使用Java的這個類。不過用起來并不會那么舒服,因為雖然Java也允許用戶創建新的類型,但是這些類型用起來并不會給人原生支持的體驗:

BigInt的實現方式很有代表性,實際上還有許多其他數值類的類型(大小數、復數、有理數、置信區間、多項式等)。某些編程語言原生地支持其中的某些數值類型。舉例來說,Lisp、Haskell和Python實現了大整數;而Fortran和Python則實現了復數。不過,如果某個語言要同時實現所有這些對數值的抽象,則只會讓語言的實現變得大到不可控的程度。不僅如此,就算有這樣的語言存在,總有某些應用會得益于語言提供的范圍之外的類型。因此,試圖在語言中提供一切的做法并不實際。Scala允許用戶通過定義易于使用的類庫來培育和定制,最終的代碼讓人感覺就像是語言本身支持的那樣。

培育新的控制結構

從前一個示例中可以看到,Scala允許我們添加新的類型,且這些類型的用法與內建的類型相同。像這樣的擴展原則也適用于控制結構。在ScalaTest這個頗為流行的Scala測試類庫中,AnyFunSuite編程風格就很好地展示了這一點。

舉個例子,下面是一個簡單的測試類,包含了兩個測試:

我們并不指望你在現階段就能完全理解AnyFunSuite這個例子,重點是在伸縮性方面,無論test還是assertThrows語法都不是Scala內建的。雖然它們看起來及運行起來都與內建的控制結構很像,但是事實上它們都是在ScalaTest類庫中定義的方法。這兩個控制結構完全獨立于Scala編程語言本身。

從這個例子中不難看出,哪怕是具體到軟件測試這樣的特定場景下,你也可以朝新的方向“培育”Scala語言。當然,為了做到這一點,我們需要有經驗的架構師和程序員,不過關鍵在于這是可行的——可以用Scala設計和實現那些能解決全新應用領域問題的抽象,且它們用起來就像是語言原生支持的一樣。

主站蜘蛛池模板: 响水县| 泸西县| 邹平县| 巫溪县| 兴安盟| 通化市| 南昌市| 浦县| 绥棱县| 循化| 胶州市| 靖安县| 德阳市| 南澳县| 临颍县| 颍上县| 双辽市| 西昌市| 永定县| 凤翔县| 长乐市| 永和县| 镇坪县| 长丰县| 饶平县| 长汀县| 邢台市| 凤凰县| 河津市| 宣化县| 宝兴县| 承德县| 嘉鱼县| 临城县| 高阳县| 阿瓦提县| 昌吉市| 广宗县| 五华县| 正安县| 高淳县|