1. 程式人生 > >Scala具體解釋---------Scala是什麽?可伸展的語言!

Scala具體解釋---------Scala是什麽?可伸展的語言!

證明 重要 用戶 處理器 pan tom 法國 per def

Scala是什麽

Scala語言的名稱來自於“可伸展的語言”。

之所以這樣命名,是由於他被設計成隨著使用者的需求而成長。你能夠把Scala應用在非常大範圍的編程任務上。從寫個小腳本到建立個大系統。

51CTO編輯推薦:Scala編程語言專題

Scala是非常easy進入的語言。

它跑在標準的Java平臺上。可以與全部的Java庫實現無縫交互。

它也是用來編寫腳本把Java控件鏈在一起的非常好的語言。可是用它來建立大系統和可重用控件的架構將更可以發揮它的力量。

從技術層面上來說,Scala是一種把面向對象和函數式編程理念增加到靜態類型語言中的混血兒。Scala的很多不同的方面都展現了面向對象和函數式編程的熔合;也許它比其它那些廣泛使用的語言更有滲透性。在可伸展性方面。這兩種編程風格具有互補的力量。

Scala的函數式編程使得它便於高速地從簡單的碎片開始建立一些有趣的東西。

它的面向對象特性又使它便於構造大型系統並使它們適應於新的需求。

Scala中這兩種風格的組合使得它有可能表達新的編程模式和控件抽象。並產生了易讀、簡潔的編程風格。因為它良好的延展性,用Scala編程將會有非常多的樂趣。

不同尺寸的程序傾向於須要不同的編程結構。

舉例來說。考慮下面的Scala程序:

  1. var capital = Map("US"->"Washington", "France" -> "Paris"
    )
  2. capital += ("Japan" -> "Tokyo")
  3. println(capital("France"))

這段程序建立了一個國家和它們的首都之間的映射表,添加了一個新的綁定("Japan"->"Tokyo")。然後打印了與法國相關的首都。

本例中的聲明都是高層次的。也就是說。沒有被外加的分號或者類型凝視弄得亂糟糟的。實際上,這樣的感覺就好像那種現代的“腳本化”語言,比方。Perl,Python或者Ruby。這些語言的一個普遍特征,與上例有關的,就是它們都在語法層面上支持“關聯映射”。

關聯映射很實用,由於它能讓程序易讀和清晰。然而。有些時候你也許不贊成它們的這樣的“均碼”哲學,由於你須要用一種更加細粒度地去控制在你程序中用到的映射的屬性。Scala能夠在你須要的時候提供這樣的細粒度的控制。由於映射在Scala裏並非語法特性。

它們是庫抽象,你能夠擴展或者改造。

在上面的程序裏。你將獲得一個缺省的Map實現,只是你也能夠非常輕松地改變它。例如說,你能夠定義個特別的實現,如HashMap或TreeMap,或者你能夠特定這個映射必須是線程安全的,混入:mix-in個SynchronizedMap特色:trait。你還能夠給映射特定一個缺省值,或你能夠重載你創建的映射的隨意方法。每一個樣例裏,你都能夠如上例所看到的那樣使用相同簡單的映射訪問語法。

這個樣例顯示了Scala帶給你的方便性和靈活性,能夠讓你更好的了解Scala是什麽。Scala有一整套的方便構件來幫助你高速啟動及讓你用一種愉悅清晰的狀態編程。

與此同一時候。你有信心你不會讓語言過度發育。

你總能夠把程序按你的須要裁剪。由於全部的東西都是基於庫模塊的。能夠按照須要選擇和改動。

Scala是什麽:培育新的類型

Eric Raymond把大教堂和雜貨鋪作為軟件開發的兩個隱喻。 大教堂是幾近於完美的建築物,要花非常長的時間建設。一旦建成了,就長時間保持不變。

相對來說,雜貨鋪則天天在被工作當中的人調整和擴展。

Raymond的文章中,雜貨鋪是對於開源軟件開發的隱喻。

Guy Steele在他的講話“發展一門語言”中提到相同的區別也能夠應用在語言定義中。 Scala更像一個雜貨鋪而不是大教堂,由於它被設計為讓用它編程的人擴展和改動的。

Scala並沒有提供全部你在一種“完美齊全”語言中可能須要的東西,而是把制作這些東西的工具放在了你的手中。

這兒有個樣例。

很多程序須要一個可以變得隨意大都不會溢出或者因為數學操作而“繞回”的整數類型。

Scala在庫類Scala.BigInt中定義了這樣一個類型。

這裏有一個使用了那個類型的方法定義。用以計算傳入整數的階乘值:

  1. def factorial(x: BigInt): BigInt =
  2. if (x == 0) 1 else x * factorial(x - 1)

如今,假設你調用了factorial(30),你將得到:

265252859812191058636308480000000

BigInt看上去就像一個內建的類型,由於你能夠使用整數值和這樣的類型值的操作符如*和-。

然而它僅僅是湊巧定義在Scala標準庫中的類。

假設這個類缺失了,能夠直接由隨意的Scala程序猿寫一個實現出來,舉例來說,通過包裝Java的類java.math.BigInteger(實際上,Scala的BigInt就是這麽實現的)。

當然。你也能夠直接使用Java的類庫。

但結果卻不盡樂觀,由於雖然Java同意創建新的類,但這些類總感覺不像原生的語言支持。

  1. import java.math.BigInteger
  2. def factorial(x:BigInteger): BigInteger =
  3. if (x == BigInteger.ZERO)
  4. BigInteger.ONE
  5. else
  6. x.multiply(factorial(x.subtract(BigInteger.ONE)))

BigInt代表了更多類似於數字的類型——大十進制數,復數,分數。置信區間,多項式——諸如此類。一些編程語言原生實現了當中的一些類型。舉例來說。Lisp,Haskell和Python實現了大整數。Fortran和Python實現了復數。可是不論什麽語言想要嘗試同一時候實現全部的這些抽象類型將非常easy變得太大而難以管理。

更進一步,即使假設有這種語言,總有些應用會使用其它的沒支持的數字類型。所以嘗試在一種語言裏提供全部東西的解決之道不可能非常好地伸展。

取而代之。Scala同意用戶在他們須要的方向上通過定義易用庫來發展和改造語言,使得這些特性感覺上好像原生語言支持一樣。

培育新的控制結構

前面的樣例演示了Scala讓你添加新的類型。使得它們用起來方便得像內建類型一樣。相同的擴展理念也應用在控制結構上。

這樣的類型的擴展是由Scala的“基於行動類”的並發編程API闡明的。

隨著近年多核處理器的激增。為了獲取可接受的性能,你將必須在應用中運用很多其它的並行機制。經常這就意味著重寫你的代碼來讓計算分布到若幹並發線程上。不幸的是,創建依賴性的多線程程序在實踐中被證明是非常具有挑戰性的。Java的線程模型是環繞著共享內存和鎖建立的。尤其是當系統在大小和復雜度都得到提升的時候。這樣的模型經常是不可理喻的。

非常難說程序裏面沒有資源競爭或潛藏的死鎖——有些東西不是能在測試裏面檢驗得出,而也許僅僅在投入生產後才表現出來。而大致能夠覺得比較安全的可選方案是消息傳遞架構。比如在Erlang編程語言中應用的“行動類”方案。

Java伴隨著一個豐富的,基於線程的並發庫。Scala能夠像其它JavaAPI那樣使用它編程。然而,Scala也提供了一個實質上實現了Erlang的行動類模型的附加庫。

行動類是可以實現於線程之上的並發抽象。

它們通過在彼此間發送消息實現通信。每一個行動類都能實現兩個基本操作,消息的發送和接受。發送操作,用一個驚嘆號表示,發送消息給一個行動類。這裏用一個命名為recipient的行動類舉比例如以下:

  1. recipient ! msg

發送是異步的;就是說。發送的行動類能夠在一瞬間完畢,而不須要等待消息被接受和處理。

每個行動類都有一個信箱:mailbox把進入的消息排成隊列。

行動類通過receive代碼塊處理信箱中受到的消息:

  1. receive {
  2. case Msg1 => ... // handle Msg1
  3. case Msg2 => ... // handle Msg2
  4. // ...
  5. }

接收代碼塊由很多case語句組成,每個都用一個消息模板查詢信箱。信箱中第一個符合不論什麽case的消息被選中,而且運行對應的動作。

假設信箱中不含有不論什麽符合不論什麽case的消息,行動類將休眠等待新進的消息。

這裏舉一個簡單的Scala行動類實現檢查值(cheksum)計算器服務的樣例:

  1. actor {
  2. var sum = 0
  3. loop {
  4. receive {
  5. case Data(bytes) => sum += hash(bytes)
  6. case GetSum(requester) => requester ! sum
  7. }
  8. }
  9. }

這個行動類首先定義了一個名為sum的本地變量。並賦了初值為零。然後就用receive段落反復等待在消息循環中。假設收到了Data消息,就把發送的bytes取哈希值加到sum變量中。假設收到了GetSum消息。就用消息發送requester!sum把當前sum值發回給requester。requester字段嵌入在GetSum消息裏;它通常指出創建請求的行動類。

眼下我們並不指望你能全然明確行動類樣例。

實際上,對於可伸展性這個話題來說這個樣例裏面最重要的是,不論是actor還是loop還是receive還是發送消息的符號“!”,這些都不是Scala內建的操作符。雖然actor,loop和receive看上去或者表現上都如此接近於控制結構如while或者for循環,實際上它們是定義在Scala的行動類庫裏面的方法。相同,雖然“!”看上去像是個內建的操作符。它也只是是定義在行動類庫裏面的方法。全部這四個構件都是全然獨立於Scala語言的。

receive代碼塊和發送“!”語法讓Scala看上去更像Erlang裏的樣子,可是在Erlang裏面,這些構件是內建在語言中的。Scala還實現了Erlang其它並發編程構件的大多數,諸如監控失敗行動類和超時類。總體來說,行動類已變成表達並發和分布式計算的很好的辦法。

雖然它們是定義在庫裏的,給人的感覺就像行動類是Scala語言總體的部分。

本例演示了你能夠向新的方向“培養”Scala語言乃至像並發編程這種特性。前提是,你須要一個好的架構和程序猿來做這種事。但重要的事情是這的確可行——你能夠在Scala裏面設計和實現抽象結構,從而高速投入新的應用領域,卻仍然感覺像是原生的語言支持。

本文節選自Martin Odersky,Lex Spoon和Bill Venners所著,Regular翻譯的《Programming in Scala》的第一章。

本文借鑒於http://developer.51cto.com/art/200907/134865.htm

Scala具體解釋---------Scala是什麽?可伸展的語言!