Scala是一門(mén)多范式的編程語(yǔ)言,一種類(lèi)似java的編程語(yǔ)言,設(shè)計(jì)初衷是實(shí)現(xiàn)可伸縮的語(yǔ)言、并集成面向?qū)ο缶幊毯秃瘮?shù)式編程的各種特性。
編程語(yǔ)言
簡(jiǎn)介
Scala編程語(yǔ)言抓住了很多開(kāi)發(fā)者的眼球。如果你粗略瀏覽Scala的網(wǎng)站,你會(huì)覺(jué)得Scala是一種純粹的面向?qū)ο缶幊陶Z(yǔ)言,而又無(wú)縫地結(jié)合了命令式編程和函數(shù)式編程風(fēng)格。Christopher Diggins認(rèn)為:
不太久之前編程語(yǔ)言還可以毫無(wú)疑意地歸類(lèi)成“命令式”或者“函數(shù)式”或者“面向?qū)ο蟆薄cala代表了一個(gè)新的語(yǔ)言品種,它抹平了這些人為劃分的界限。
根據(jù)David Rupp在博客中的說(shuō)法,Scala可能是下一代Java。這么高的評(píng)價(jià)讓人不禁想看看它到底是什么東西。
Scala有幾項(xiàng)關(guān)鍵特性表明了它的面向?qū)ο蟮谋举|(zhì)。例如,Scala中的每個(gè)值都是一個(gè)對(duì)象,包括基本數(shù)據(jù)類(lèi)型(即布爾值、數(shù)字等)在內(nèi),連函數(shù)也是對(duì)象。另外,類(lèi)可以被子類(lèi)化,而且Scala還提供了基于mixin的組合(mixin-based composition)。
與只支持單繼承的語(yǔ)言相比,Scala具有更廣泛意義上的類(lèi)重用。Scala允許定義新類(lèi)的時(shí)候重用“一個(gè)類(lèi)中新增的成員定義(即相較于其父類(lèi)的差異之處)”。Scala稱(chēng)之為mixin類(lèi)組合。
Scala還包含了若干函數(shù)式語(yǔ)言的關(guān)鍵概念,包括高階函數(shù)(Higher-Order 函數(shù))、局部套用(Currying)、嵌套函數(shù)(Nested Function)、序列解讀(Sequence Comprehensions)等等。
Scala是靜態(tài)類(lèi)型的,這就允許它提供泛型類(lèi)、內(nèi)部類(lèi)、甚至多態(tài)方法(Polymorphic Method)。另外值得一提的是,Scala被特意設(shè)計(jì)成能夠與Java和.NET互操作。Scala當(dāng)前版本還不能在.NET上運(yùn)行(雖然上一版可以-_-b),但按照計(jì)劃將來(lái)可以在.NET上運(yùn)行。
Scala可以與Java互操作。它用scalac這個(gè)編譯器把源文件編譯成Java的class文件(即在JavaOS上運(yùn)行的字節(jié)碼)。你可以從Scala中調(diào)用所有的Java類(lèi)庫(kù),也同樣可以從Java應(yīng)用程序中調(diào)用Scala的代碼。用David Rupp的話來(lái)說(shuō),
它也可以訪問(wèn)現(xiàn)存的數(shù)之不盡的Java類(lèi)庫(kù),這讓?zhuān)撛诘兀┻w移到Scala更加容易。
這讓Scala得以使用為Java1.4、5.0或者6.0編寫(xiě)的巨量的Java類(lèi)庫(kù)和框架,Scala會(huì)經(jīng)常性地針對(duì)這幾個(gè)版本的Java進(jìn)行測(cè)試。Scala可能也可以在更早版本的Java上運(yùn)行,但沒(méi)有經(jīng)過(guò)正式的測(cè)試。Scala以BSD許可發(fā)布,并且數(shù)年前就已經(jīng)被認(rèn)為相當(dāng)穩(wěn)定了。
說(shuō)了這么多,我們還沒(méi)有回答一個(gè)問(wèn)題:“為什么我要使用Scala?”Scala的設(shè)計(jì)始終貫穿著一個(gè)理念:
創(chuàng)造一種更好地支持組件的語(yǔ)言。(《The Scala Programming Language》,Donna Malayeri)
也就是說(shuō)軟件應(yīng)該由可重用的部件構(gòu)造而成。Scala旨在提供一種編程語(yǔ)言,能夠統(tǒng)一和一般化分別來(lái)自面向?qū)ο蠛秃瘮?shù)式兩種不同風(fēng)格的關(guān)鍵概念。
藉著這個(gè)目標(biāo)與設(shè)計(jì),Scala得以提供一些出眾的特性,包括:
* 面向?qū)ο箫L(fēng)格
* 函數(shù)式風(fēng)格
* 更高層的并發(fā)模型
Scala把Erlang風(fēng)格的基于actor的并發(fā)帶進(jìn)了JavaOS。開(kāi)發(fā)者可以利用Scala的actor模型在JVM上設(shè)計(jì)具伸縮性的并發(fā)應(yīng)用程序,它會(huì)自動(dòng)獲得多核心處理器帶來(lái)的優(yōu)勢(shì),而不必依照復(fù)雜的Java線程模型來(lái)編寫(xiě)程序。
* 輕量級(jí)的函數(shù)語(yǔ)法
o 高階
o 嵌套
o 局部套用(Currying)
o 匿名
* 與XML集成
o 可在Scala程序中直接書(shū)寫(xiě)XML
o 可將XML轉(zhuǎn)換成Scala類(lèi)
* 與Java無(wú)縫地互操作
Scala的風(fēng)格和特性已經(jīng)吸引了大量的開(kāi)發(fā)者,比如Debasish Ghosh就覺(jué)得:
我已經(jīng)把玩了Scala好一陣子,可以說(shuō)我絕對(duì)享受這個(gè)語(yǔ)言的創(chuàng)新之處。
總而言之,Scala是一種函數(shù)式面向?qū)ο笳Z(yǔ)言,它融匯了許多前所未有的特性,而同時(shí)又運(yùn)行于JavaOS之上。隨著開(kāi)發(fā)者對(duì)Scala的興趣日增,以及越來(lái)越多的工具支持,無(wú)疑Scala語(yǔ)言將成為你手上一件必不可少的工具。
Scala與Groovy的對(duì)比
一篇名為“Scala,Groovy的殺手? ”的博客對(duì)Scala和Groovy進(jìn)行了對(duì)比:
Scala和Groovy之間的核心區(qū)別在于前者是靜態(tài)類(lèi)型的。有些人可能爭(zhēng)辯說(shuō)這使得達(dá)到腳本化目標(biāo)變得更加復(fù)雜了,而腳本化正是Groovy的動(dòng)機(jī)。然而,Scala有完整的體系特征,這使Groovy看上去更像個(gè)玩具。比如,Scala有“sequence comprehensions”。該要素導(dǎo)致對(duì)算法的表述非常緊湊和強(qiáng)大。
Scala還有更多被證明是非常有用的特性,如嵌套類(lèi),currying和代數(shù)類(lèi)型模式匹配。它還支持類(lèi)似于JDK1.5所增加的泛型和注解。這些還都只是冰山一角。
之后,Derek Young撰文“Scala對(duì)比Groovy:靜態(tài)類(lèi)型是性能的關(guān)鍵”。在文中他舉了一個(gè)實(shí)際的例子,試圖說(shuō)明針對(duì)同樣的算法,Scala的性能遠(yuǎn)高于Groovy。
然而,Scala并不是盡善盡美的,它也有一些明顯的缺陷。Rick Hightower在發(fā)表的一篇博客中,尖銳地批評(píng)了Scala的語(yǔ)法問(wèn)題:
Scala并不是更好的選擇。在閱讀了Scala的文檔之后,我的想法是:雖然這種語(yǔ)言的特性聽(tīng)起來(lái)挺好,但是語(yǔ)法卻讓我想放棄。為什么事情非要為了不同而不同?Scala讓Groovy看起來(lái)比以前更加美味可口。
憎恨是個(gè)很強(qiáng)烈的詞。我恨Scala的語(yǔ)法。請(qǐng)不要再推進(jìn)這種語(yǔ)法了。……Scala有好的思想嗎?有。借用過(guò)來(lái)就行了……
總而言之,Scala看起來(lái)像下一個(gè)被過(guò)度宣傳的語(yǔ)言。只需要把其精華引入到Groovy中,然后扔掉那些糟糕的語(yǔ)法。我最喜歡的Scala特性是推理類(lèi)型和強(qiáng)類(lèi)型。C#3.0也有這些。(我不用C#,不見(jiàn)得我不喜歡它的一些特性。)
Rick Hightower還建議Sun應(yīng)該在Groovy上進(jìn)行投資,而不是對(duì)jruby作無(wú)謂的投資。
Groovy更像Java,更容易上手,語(yǔ)法也讓開(kāi)發(fā)者不反感。為什么Sun在JRuby上投那么多錢(qián)呢?
投資應(yīng)該給Groovy。這樣了解Java的開(kāi)發(fā)者可以更快地學(xué)習(xí)Groovy,而且如果有工具支持他們,那么就更可能這樣做。
為了說(shuō)明Sun投資在Ruby上的不明智,Rick Hightower還引用了一幅統(tǒng)計(jì)圖表來(lái)說(shuō)明企業(yè)采用Ruby的趨勢(shì)還是比較低的:
另外,無(wú)論是Ruby、Scala還是Groovy都有對(duì)應(yīng)的Web框架,且對(duì)應(yīng)的框架都是用各自對(duì)應(yīng)的語(yǔ)言編寫(xiě)的。這些框架分別是Rails、升力和Grails。盡管lift和grails中的許多東西都從Ruby on Rails借鑒來(lái)的,但是Grails對(duì)其他已有Java技術(shù)框架進(jìn)行了很好的繼承,這無(wú)疑會(huì)保護(hù)用戶或廠商在這方面的已有投資。Grails框架參考文檔中這樣描述:
Grails構(gòu)建在這些概念之上,并且顯著地減少了在Java平臺(tái)上構(gòu)建Web應(yīng)用的復(fù)雜程度。不同的是,這些是建立在已確立的如Spring和Hibernate這樣的Java技術(shù)之上的。
Scala和Groovy兩種語(yǔ)言都在快速發(fā)展的過(guò)程中。就情況來(lái)看,Groovy的優(yōu)勢(shì)在于易用性以及與Java無(wú)縫銜接,Scala的優(yōu)勢(shì)在于性能和一些高級(jí)特性,如果在發(fā)展過(guò)程中兩者能互相借鑒對(duì)方的優(yōu)點(diǎn)來(lái)充實(shí)自身,對(duì)開(kāi)發(fā)者來(lái)講無(wú)疑是福音。正如第一篇所引用的博客作者最后提到的那樣:
大家并不想看到一場(chǎng)殊死斗爭(zhēng),而是想看到更注重實(shí)效思想的Groovy團(tuán)隊(duì)能與更具有學(xué)術(shù)思想的Scala團(tuán)隊(duì)一起合作,制作出一門(mén)既強(qiáng)大又易用的語(yǔ)言。
你會(huì)將賭注押在誰(shuí)身上呢?
Scala 發(fā)音為 /?skɑ?l?, ?ske?l?/)是一種多范式的編程語(yǔ)言,設(shè)計(jì)意圖是要集成面向?qū)ο缶幊毯秃瘮?shù)式編程的各種特性。
技巧
1、不要陷入C++一樣的、不斷膨脹的問(wèn)題里,留下太多的選擇,且沒(méi)有清晰的最佳實(shí)踐。這導(dǎo)致每個(gè)人都在選擇不同的子集。要提供適應(yīng)的指導(dǎo)。
2、記住,反對(duì)不良的設(shè)計(jì)功能與增加新功能同等重要——這很殘酷。
3、考慮拆分語(yǔ)言為生產(chǎn)環(huán)境創(chuàng)建可行的標(biāo)準(zhǔn)。為學(xué)術(shù)世界節(jié)省成本是一個(gè)明智的選擇。迎合企業(yè)的需要,獲得更大的采用。
4、庫(kù)的編寫(xiě)者應(yīng)該看看Java API,確認(rèn)是否應(yīng)該有功能調(diào)用或結(jié)構(gòu)化功能,為了更好的閱讀。不要為了流動(dòng)性在跳躍太大來(lái)與Ruby競(jìng)爭(zhēng)。
5、最后,當(dāng)人們提出的建設(shè)性的批評(píng)時(shí),不要感到失望。如果同樣的報(bào)怨不斷出現(xiàn),那就說(shuō)明應(yīng)該重視一下。
平臺(tái)和許可證
Scala運(yùn)行于Java平臺(tái)(Java虛擬機(jī)),并兼容現(xiàn)有的Java程序。它也能運(yùn)行于Java ME, CLDC(Java Platform, Micro Edition Connected Limited Device Configuration)上。還有另一.NET平臺(tái)的實(shí)現(xiàn),不過(guò)該版本更新有些滯后。
Scala的編譯模型(獨(dú)立編譯,動(dòng)態(tài)類(lèi)加載)與Java和C#一樣,所以Scala代碼可以調(diào)用Java類(lèi)庫(kù)(對(duì)于.NET實(shí)現(xiàn)則可調(diào)用.NET類(lèi)庫(kù)) 。
Scala包中包含了編譯器和類(lèi)庫(kù),以BSD許可證發(fā)布。
發(fā)展歷史
聯(lián)邦理工學(xué)院洛桑(洛桑聯(lián)邦理工學(xué)院)的Martin Odersky于2001年基于Funnel的工作開(kāi)始設(shè)計(jì)Scala。Funnel是把函數(shù)式編程思想和Petri網(wǎng)相結(jié)合的一種編程語(yǔ)言。Odersky先前的工作是Generic Java和javac(Sun Java編譯器)。Java平臺(tái)的Scala于2003年底/2004年初發(fā)布。.NET平臺(tái)的Scala發(fā)布于2004年6月。該語(yǔ)言第二個(gè)版本,v2.0,發(fā)布于2006年3月。
截至2009年9月,最新版本是版本2.7.6 。Scala 2.8預(yù)計(jì)的特性包括重寫(xiě)的Scala類(lèi)庫(kù)(Scala collections library)、方法的命名參數(shù)和默認(rèn)參數(shù)、包對(duì)象(package object),以及Continuation.
2009年4月,Twitter宣布他們已經(jīng)把大部分后端程序從Ruby遷移到Scala,其余部分也打算要遷移。此外, Wattzon已經(jīng)公開(kāi)宣稱(chēng),其整個(gè)平臺(tái)都已經(jīng)是基于Scala基礎(chǔ)設(shè)施編寫(xiě)的。
特性
面向?qū)ο筇匦?/p>
Scala是一種純面向?qū)ο蟮恼Z(yǔ)言,每一個(gè)值都是對(duì)象。對(duì)象的數(shù)據(jù)類(lèi)型以及行為由類(lèi)和特征(Trait)描述。類(lèi)抽象機(jī)制的擴(kuò)展有兩種途徑。一種途徑是子類(lèi)繼承,另一種途徑是靈活的混入(Mixin)機(jī)制。這兩種途徑能避免多重繼承的種種問(wèn)題。
函數(shù)式編程
Scala也是一種函數(shù)式語(yǔ)言,其函數(shù)也能當(dāng)成值來(lái)使用。Scala提供了輕量級(jí)的語(yǔ)法用以定義匿名函數(shù),支持高階函數(shù),允許嵌套多層函數(shù),并支持柯里化。Scala的Case Class及其內(nèi)置的模式匹配相當(dāng)于函數(shù)式編程語(yǔ)言中常用的代數(shù)類(lèi)型(Algebraic Type)。
更進(jìn)一步,程序員可以利用Scala的模式匹配,編寫(xiě)類(lèi)似正則表達(dá)式的代碼處理XML數(shù)據(jù)。在這些情形中,順序容器的推導(dǎo)式(comprehension)功能對(duì)編寫(xiě)公式化查詢(xún)非常有用。
由于JavaOS不支持尾部遞歸,Scala也不能完全支持尾部遞歸優(yōu)化。不過(guò),在簡(jiǎn)單的情況下,Scala編譯器可以把尾部遞歸優(yōu)化成循環(huán)。
以下代碼以函數(shù)式風(fēng)格實(shí)現(xiàn)了快速排序算法,可以與Erlang快速排序的例子做個(gè)比較:
def qsort(list: List[Int]): List[Int]=
list match{
case Nil => Nil
case pivot::tail =>
qsort(for(i <- tail if i < pivot)yield i)::: pivot :: qsort(for(i <- tail if i >= pivot)yield i)
}
靜態(tài)類(lèi)型
Scala是具備類(lèi)型系統(tǒng),通過(guò)編譯時(shí)的檢查,保證代碼的安全性和一致性。類(lèi)型系統(tǒng)具體支持以下特性:
泛型類(lèi),型變注釋?zhuān)╒ariance Annotation),類(lèi)型繼承結(jié)構(gòu)的上限和下限,把類(lèi)別和抽象類(lèi)型作為對(duì)象成員,復(fù)合類(lèi)型,引用自己時(shí)顯式指定類(lèi)型,視圖,多態(tài)方法。
擴(kuò)展性
Scala的設(shè)計(jì)承認(rèn)一個(gè)事實(shí),即在實(shí)踐中,某個(gè)領(lǐng)域特定的應(yīng)用程序開(kāi)發(fā)往往需要特定于該領(lǐng)域的語(yǔ)言擴(kuò)展。Scala提供了許多獨(dú)特的語(yǔ)言機(jī)制,可以以庫(kù)的形式輕易無(wú)縫添加新的語(yǔ)言結(jié)構(gòu):
任何方法可用作前綴或后綴操作符,可以根據(jù)預(yù)期類(lèi)型自動(dòng)構(gòu)造閉包。聯(lián)合使用以上兩個(gè)特性,使你可以定義新的語(yǔ)句而無(wú)須擴(kuò)展語(yǔ)法也無(wú)須使用宏之類(lèi)的元編程特性。
使用Scala的框架
lift是一個(gè)開(kāi)源的Web應(yīng)用框架,旨在提供類(lèi)似Ruby on Rails的東西。因?yàn)長(zhǎng)ift使用了Scala,所以Lift應(yīng)用程序可以使用所有的Java庫(kù)和Web容器。
測(cè)試
以下是測(cè)試Scala代碼的一些方式:
ScalaTest ScalaCheck,類(lèi)似于Haskell的QuickCheck的一個(gè)庫(kù)specs,一個(gè)用于Scala的行為驅(qū)動(dòng)的開(kāi)發(fā)工具庫(kù)JUnit內(nèi)置的Scala庫(kù)SUnit已經(jīng)不贊成使用,將會(huì)在2.8.0版中移除,見(jiàn)SUnit文檔。
范例
以下是用Scala編寫(xiě)的典型的Hello Scala中文程序:
object HelloScalachina extends Application { println("Hello, Scala中文!")}
或
object HelloScalachina {def main(args: Array[String]){ println("Hello, Scala中文!")}}
請(qǐng)注意它與Java的Hello Scala中文應(yīng)用程序有哪些相似之處。一個(gè)顯著區(qū)別在于,Scala版的Hello Scala中文程序沒(méi)有把任何東西標(biāo)記為static,而是用object 關(guān)鍵字創(chuàng)建了一個(gè)單件。
假設(shè)該程序保存為HelloScalachina.scala文件,接下來(lái)可以通過(guò)以下命令行進(jìn)行編譯:
> scalac HelloScalaChinascala
若要運(yùn)行:
> scala -classpath . HelloScalachina
這與編譯和運(yùn)行Java的“Hello Scala中文”程序是不是很像呢?事實(shí)上,Scala的編譯和執(zhí)行模型與Java是等效的,因而它也兼容于Java的構(gòu)建工具,比如Ant.
直接使用Scala解釋器也可以運(yùn)行該程序,使用選項(xiàng)-i (從文件加載代碼)和選項(xiàng)-e (若要運(yùn)行額外的代碼,就得實(shí)際執(zhí)行HelloScalachina對(duì)象的方法)即可:
> scala -i HelloScalaChinascala -e 'HelloScalachina.main(null)'
書(shū)籍
書(shū)名:Scala編程思想(原書(shū)第2版)
作者:[美]布魯斯·埃克爾(Bruce Eckel),戴安娜·馬什(Dianne Marsh)著
ISBN:9787111517405
頁(yè)數(shù):320
開(kāi)本:16開(kāi)
定價(jià):69.00元
出版時(shí)間:2015年11月
出版社:機(jī)械工業(yè)出版社
內(nèi)容簡(jiǎn)介:
《Scala編程思想(原書(shū)第2版)》介紹了Scala的基礎(chǔ)特性,采用短小精悍的“原子”解構(gòu)Scala語(yǔ)言的元素和方法。一個(gè)“原子”即為一個(gè)小型知識(shí)點(diǎn),通過(guò)代碼示例引導(dǎo)讀者逐步領(lǐng)悟Scala的要義,結(jié)合練習(xí)鼓勵(lì)讀者在實(shí)踐中讀懂并寫(xiě)出地道的Scala代碼。訪問(wèn)下載練習(xí)解答和代碼示例,還可了解本書(shū)英文版的全新動(dòng)態(tài)。
本書(shū)無(wú)需編程背景知識(shí),適合Scala初學(xué)者閱讀。同時(shí),本書(shū)也為有經(jīng)驗(yàn)的程序員提供了“快車(chē)道”,共同探索編程語(yǔ)言未來(lái)的模樣。
·本書(shū)原則:積步以至千里,無(wú)任何前向引用,無(wú)任何對(duì)其他語(yǔ)言的引用,事實(shí)勝于雄辯,實(shí)踐出真知。
·何謂“原子”:從Scala中提煉出一個(gè)可運(yùn)行的核心功能子集,形成眾多短小精悍的“原子”,再輔以練習(xí)和解答,使整個(gè)閱讀過(guò)程成為帶有許多檢查點(diǎn)的漸進(jìn)式學(xué)習(xí)體驗(yàn),而不是在Scala龐大的知識(shí)體系中囫圇吞棗。
·寫(xiě)給未來(lái)的代碼:相比于Java,Scala更加簡(jiǎn)潔、合理、高效、強(qiáng)大。但本書(shū)包含的只是編程和Scala的基礎(chǔ)知識(shí),它們不會(huì)使你暈頭轉(zhuǎn)向,而是在踏上更高級(jí)的編程之路時(shí)祝你一臂之力。
參考資料 >
編程語(yǔ)言 Scala.www.oschina.net.2018-10-29
Scala編程思想(原書(shū)第2版).豆瓣讀書(shū).2015-11-16