第一步 ,學(xué)習(xí)使用交互式Scala解釋器
開(kāi)始使用Scala的最簡(jiǎn)單的方式是使用交互式Scala解釋器,只要輸入Scala表達(dá)式,Scala解釋器會(huì)立即解釋執(zhí)行該語(yǔ)句并輸出結(jié)果。當(dāng)然你也可以使用如Scala IDE或IntelliJ IDEA集成開(kāi)發(fā)環(huán)境。不過(guò)本教程開(kāi)始還是以這種交互式Scala解釋器為主。
使用Scala解釋器,首先你需要下載安裝Scala運(yùn)行環(huán)境。 然后再命令行輸入scala ,則進(jìn)入scala 解釋器,下圖為L(zhǎng)inux環(huán)境下scala 解釋器界面:你可以使用:help 命令列出一些常用的Scala解釋器命令,退出Scala解釋器,輸入
1:quit

在scala > 提示符下,你可以輸入任意的Scala表達(dá)式,比如輸入 1+2
解釋器顯示:
1res0:Int=3
這行顯示包括:
一個(gè)由Scala解釋器自動(dòng)生成的變量名或者由你指定的變量名用來(lái)指向計(jì)算出來(lái)的結(jié)果(比如 res0 代表 result0變量)
一個(gè)冒號(hào),后面緊跟個(gè)變量類(lèi)型比如Int
一個(gè)等于號(hào)
計(jì)算結(jié)果,本例為1+2的結(jié)果3
resX 變量名可以用在之后的表達(dá)式中,比如 此時(shí)res0=3,如果輸入 res0 *3 ,則顯示 res1: Int =9

第二步:定義一些變量
Scala 定義了兩種類(lèi)型的變量 val 和 var ,val 類(lèi)似于Java中的final 變量,一旦初始化之后,不可以重新復(fù)制(我們可以稱(chēng)它為常變量)。而var 類(lèi)似于一般的非final變量??梢匀我庵匦沦x值。
比如定義一個(gè)字符串常變量:
1scala>valmsg="Hello,World"
2msg:String=Hello,World
這個(gè)表達(dá)式定義了一個(gè)msg變量,為字符串常量。它的類(lèi)型為 string (java.lang.string). 可以看到我們?cè)诙x這個(gè)變量時(shí)并不需要像Java一樣定義其類(lèi)型,Scala 可以根據(jù)賦值的內(nèi)容推算出變量的類(lèi)型。這在Scala語(yǔ)言中成為“type inference”。當(dāng)然如果你愿意,你也可以采用和Java一樣的方法,明確指定變量的類(lèi)型,如
1scala>valmsg2:String="Hello again,world"
2msg2:String=Hello again,world
不過(guò)這樣寫(xiě)就顯得不像Scala風(fēng)格了。此外Scala語(yǔ)句也不需要以分號(hào)結(jié)尾。 如果在命令行中需要分多行輸入,Scala解釋器在新行前面顯示“|”,表示該行接著上一行。比如
1scala>valmsg3=
2|"Hello world 3rd time"
3msg3:String=Hello world3rd time
第三步:定義一些函數(shù)
Scala既是面向?qū)ο蟮木幊陶Z(yǔ)言,也是面向函數(shù)的編程語(yǔ)言,因此函數(shù)在Scala語(yǔ)言中的地位和類(lèi)是同等第一位的。下面的代碼定義了一個(gè)簡(jiǎn)單的函數(shù)求兩個(gè)值的最大值:
1scala>defmax(x:Int,y:Int):Int={
2|if(x >y) x
3|else
4| y
5| }
6max:(x:Int, y:Int)Int
Scala函數(shù)以def定義,然后是函數(shù)的名稱(chēng)(如max),然后是以逗號(hào)分隔的參數(shù)。Scala中變量類(lèi)型是放在參數(shù)和變量的后面,以“:”隔開(kāi)。這種做的一個(gè)好處是便與”type inference”。剛開(kāi)始有些不習(xí)慣(如果你是Pascal程序員會(huì)覺(jué)的很親切)。同樣如果函數(shù)需要返回值,它的類(lèi)型也是定義在參數(shù)的后面(實(shí)際上每個(gè)Scala函數(shù)都有返回值,只是有些返回值類(lèi)型為Unit,類(lèi)似為void類(lèi)型)。
此外每個(gè)Scala表達(dá)式都有返回結(jié)果(這一點(diǎn)和Java,C#等語(yǔ)言不同),比如Scala的 if else 語(yǔ)句也是有返回值的,因此函數(shù)返回結(jié)果無(wú)需使用return語(yǔ)句。實(shí)際上在Scala代碼應(yīng)當(dāng)盡量避免使用return語(yǔ)句。函數(shù)的最后一個(gè)表達(dá)式的值就可以作為函數(shù)的結(jié)果作為返回值。
同樣由于Scala的”type inference”特點(diǎn),本例其實(shí)無(wú)需指定返回值的類(lèi)型。對(duì)于大多數(shù)函數(shù)Scala都可以推測(cè)出函數(shù)返回值的類(lèi)型,但目前來(lái)說(shuō)回溯函數(shù)(函數(shù)調(diào)用自身)還是需要指明返回結(jié)果類(lèi)型的。
下面在定義個(gè)“沒(méi)有”返回結(jié)果的函數(shù)(其它語(yǔ)言可能稱(chēng)這種無(wú)返回值的函數(shù)為程式)。
1scala>defgreet()=println("hello,world")
2greet:()Unit
greet函數(shù)的返回值類(lèi)型為Unit 表示該函數(shù)不返回任何有意義的值,Unit類(lèi)似于Java中的void類(lèi)型。這種類(lèi)型的函數(shù)主要用來(lái)獲得函數(shù)的“副作用”,比如本函數(shù)的副作用是打印招呼語(yǔ)。
第四步 編寫(xiě)Scala腳本
Scala本身是設(shè)計(jì)用來(lái)編寫(xiě)大型應(yīng)用的,但它也可以作為腳本語(yǔ)言來(lái)執(zhí)行,腳本為一系列Scala表達(dá)式構(gòu)成以完成某個(gè)任務(wù),比如前面的Hello World 腳本,你也可以使用腳本來(lái)實(shí)現(xiàn)一些比如復(fù)制文件,創(chuàng)建目錄之類(lèi)的任務(wù)。
第五步: 使用while 配合使用if實(shí)現(xiàn)循環(huán)
下面的代碼使用while實(shí)現(xiàn)一個(gè)循環(huán):
1vari=0
2while(i < args.length) {
3println (args(i))
4i+=1
5}
為了測(cè)試這段代碼,可以將該代碼存成一個(gè)文件,比如printargs.scala ,將該語(yǔ)句作為腳本運(yùn)行,比如在命令行中輸入
scala printargs.scala I like Scala
則顯示:

這里要注意的是Scala不支持?。玦,i++ 運(yùn)算符,因此需要使用i+=1 來(lái)加一。 這段代碼看起來(lái)和Java代碼差不多,實(shí)際上while 也是一個(gè)函數(shù),你自動(dòng)可以利用scala語(yǔ)言的擴(kuò)展性,實(shí)現(xiàn)while 語(yǔ)句,使它看起來(lái)和Scala語(yǔ)言自帶的關(guān)鍵字一樣調(diào)用。
Scala訪問(wèn)數(shù)組的語(yǔ)法是使用()而非[].
這里介紹了使用while來(lái)實(shí)現(xiàn)循環(huán),但這種實(shí)現(xiàn)循環(huán)的方法并不是最好的Scala風(fēng)格,在下一步介紹使用一種更好的方法來(lái)避免通過(guò)索引來(lái)枚舉數(shù)組元素。
第六步:使用 foreach和 for 來(lái)實(shí)現(xiàn)迭代
第五步使用while來(lái)實(shí)現(xiàn)循環(huán),和使用Java實(shí)現(xiàn)無(wú)太大差異,而Scala是面向函數(shù)的語(yǔ)言,更好的方法是采用“函數(shù)式“風(fēng)格來(lái)編寫(xiě)代碼。比如上面的循環(huán),使用foreach方法如下:
1args.foreach(arg=> println(arg))
該表達(dá)式,調(diào)用args的foreach方法,傳入一個(gè)參數(shù),這個(gè)參數(shù)類(lèi)型也是一個(gè)函數(shù)(lambda表達(dá)式,和C#中概念類(lèi)似)。這段代碼可以再寫(xiě)的精簡(jiǎn)些,你可以利用Scala支持的縮寫(xiě)形式,如果一個(gè)函數(shù)只有一個(gè)參數(shù)并且只包含一個(gè)表達(dá)式,那么你無(wú)需明確指明參數(shù)。因此上面的代碼可以寫(xiě)成:
1args.foreach( println)
Scala中也提供了一個(gè)稱(chēng)為“for comprehension”的比Java中for表達(dá)式功能更強(qiáng)大?!癴or comprehension”(抱歉找不到合適的中文詞來(lái)翻譯這個(gè)術(shù)語(yǔ),姑且使用for表達(dá)式)將在后面介紹,這里先使用for來(lái)實(shí)現(xiàn)前面的例子:
1for(arg <-args)
2println(arg)