鍍金池/ 教程/ Scala/ 起步 Scala
包對(duì)象
Ordered Trait
組合和繼承–定義 final 成員
基本數(shù)據(jù)類型
Match 表達(dá)式
類和對(duì)象 (三)
操作基本數(shù)據(jù)類型
for 表達(dá)式
組合和繼承–重載成員函數(shù)和方法
類和對(duì)象 (二)
組合和繼承–定義 factory 對(duì)象
組合和繼承–多態(tài)和動(dòng)態(tài)綁定
Trait 的基本概念
if 表達(dá)式
組合和繼承–抽象類
函數(shù)–函數(shù)字面量的一些簡(jiǎn)化寫法
while 循環(huán)
組合和繼承–使用組合還是繼承?
訪問控制修飾符
Trait 示例–Rectangular 對(duì)象
組合和繼承–定義參數(shù)化成員變量
組合和繼承–定義無參數(shù)方法
類和對(duì)象 (一)
函數(shù)–閉包
函數(shù)–類成員函數(shù)
Scala 基本數(shù)據(jù)類型的實(shí)現(xiàn)方法
try 表達(dá)式處理異常
選擇瘦接口還是胖接口設(shè)計(jì)?
組合和繼承–小結(jié)
創(chuàng)建新的控制結(jié)構(gòu)
使用 import
為訪問控制修飾符添加作用域
Scala 的類層次關(guān)系
類和對(duì)象 (五)
傳名參數(shù)
柯里化函數(shù)
函數(shù)–頭等公民
組合和組合和繼承–定義 heighten 和 widen 函數(shù)
使用 Package–將代碼放入包中
隱含的 import
所有類的公共子類–底層類型
進(jìn)一步 Scala
函數(shù)–局部函數(shù)
引用包中的代碼
組合和繼承–使用 override 修飾符
組合和繼承–實(shí)現(xiàn)類 Element 的 above,beside 和 toString()方法
類和對(duì)象 (四)
函數(shù)–尾遞歸
沒有“break”和“continue”的日子
組合和繼承–調(diào)用基類構(gòu)造函數(shù)
減低代碼重復(fù)
函數(shù)–函數(shù)–可變參數(shù),命名參數(shù),缺省參數(shù)
起步 Scala
組合和繼承–擴(kuò)展類
函數(shù)–部分應(yīng)用的函數(shù)
開始神奇的 Scala編程之旅
組合和繼承–概述
Trait 用來實(shí)現(xiàn)可疊加的修改操作

起步 Scala

在詳細(xì)介紹 Scala 編程之前,我們先用兩篇文章給你一個(gè) Scala 的整體印象,更重要的是讓你開始寫代碼。強(qiáng)烈建議初學(xué) Scala 編程者編譯運(yùn)行本教程的每個(gè)示例。如果你是個(gè)非常有經(jīng)驗(yàn)的程序員,那么前面的這兩篇文章可以使得你或的足夠的知識(shí)開始編寫一些實(shí)用的程序。

第一步,學(xué)習(xí)使用交互式 Scala 解釋器

開始使用 Scala 的最簡(jiǎn)單的方式是使用交互式 Scala 解釋器,只要輸入 Scala 表達(dá)式,Scala 解釋器會(huì)立即解釋執(zhí)行該語句并輸出結(jié)果。當(dāng)然你也可以使用如 Scala IDE 或 IntelliJ IDEA 集成開發(fā)環(huán)境。不過本教程開始還是以這種交互式Scala解釋器為主。

使用 Scala 解釋器,首先你需要下載安裝Scala運(yùn)行環(huán)境。 然后再命令行輸入 scala ,則進(jìn)入 scala 解釋器,下圖為 Linux 環(huán)境下 scala 解釋器界面:你可以使用: help 命令列出一些常用的 Scala 解釋器命令,退出 Scala 解釋器,輸入

:quit

http://wiki.jikexueyuan.com/project/scala-development-guide/images/6.png" alt="" />

在 scala > 提示符下,你可以輸入任意的 Scala 表達(dá)式,比如輸入 1+2 解釋器顯示:

res0: Int = 3

這行顯示包括:

  • 一個(gè)由 Scala 解釋器自動(dòng)生成的變量名或者由你指定的變量名用來指向計(jì)算出來的結(jié)果(比如 res0 代表 result0 變量)
  • 一個(gè)冒號(hào),后面緊跟個(gè)變量類型比如 Int
  • 一個(gè)等于號(hào)
  • 計(jì)算結(jié)果,本例為 1+2 的結(jié)果 3

resX 變量名可以用在之后的表達(dá)式中,比如 此時(shí) res0=3,如果輸入 res0 *3,則顯示

 res1: Int =9

http://wiki.jikexueyuan.com/project/scala-development-guide/images/7.png" alt="" />

第二步:定義一些變量

Scala 定義了兩種類型的變量 val 和 var,val 類似于 Java 中的 final 變量,一旦初始化之后,不可以重新復(fù)制(我們可以稱它為常變量)。而 var 類似于一般的非 final 變量??梢匀我庵匦沦x值。

比如定義一個(gè)字符串常變量:

scala> val msg="Hello,World"
msg: String = Hello,World

這個(gè)表達(dá)式定義了一個(gè) msg 變量,為字符串常量。它的類型為 string (java.lang.string)。 可以看到我們?cè)诙x這個(gè)變量時(shí)并不需要像 Java 一樣定義其類型,Scala 可以根據(jù)賦值的內(nèi)容推算出變量的類型。這在 Scala 語言中成為 “type inference”。當(dāng)然如果你愿意,你也可以采用和 Java 一樣的方法,明確指定變量的類型,如

scala> val msg2:String ="Hello again,world"
msg2: String = Hello again,world

不過這樣寫就顯得不像 Scala 風(fēng)格了。此外 Scala 語句也不需要以分號(hào)結(jié)尾。 如果在命令行中需要分多行輸入,Scala 解釋器在新行前面顯示“|”,表示該行接著上一行。比如

scala> val msg3=
     | "Hello world 3rd time"
msg3: String = Hello world 3rd time

第三步:定義一些函數(shù)

Scala 既是面向?qū)ο蟮木幊陶Z言,也是面向函數(shù)的編程語言,因此函數(shù)在 Scala 語言中的地位和類是同等第一位的。下面的代碼定義了一個(gè)簡(jiǎn)單的函數(shù)求兩個(gè)值的最大值:

scala> def max(x:Int,y:Int) : Int ={
     | if (x >y) x
     | else
     | y
     | }
max: (x: Int, y: Int)Int

Scala 函數(shù)以 def 定義,然后是函數(shù)的名稱(如 max),然后是以逗號(hào)分隔的參數(shù)。Scala 中變量類型是放在參數(shù)和變量的后面,以“:”隔開。這種做的一個(gè)好處是便與 “type inference”。剛開始有些不習(xí)慣(如果你是 Pascal 程序員會(huì)覺的很親切)。同樣如果函數(shù)需要返回值,它的類型也是定義在參數(shù)的后面(實(shí)際上每個(gè) Scala 函數(shù)都有返回值,只是有些返回值類型為 Unit,類似為 void 類型)。

此外每個(gè) Scala 表達(dá)式都有返回結(jié)果(這一點(diǎn)和 Java,C# 等語言不同),比如 Scala 的 if else 語句也是有返回值的,因此函數(shù)返回結(jié)果無需使用 return 語句。實(shí)際上在 Scala 代碼應(yīng)當(dāng)盡量避免使用 return 語句。函數(shù)的最后一個(gè)表達(dá)式的值就可以作為函數(shù)的結(jié)果作為返回值。

同樣由于 Scala 的 “type inference” 特點(diǎn),本例其實(shí)無需指定返回值的類型。對(duì)于大多數(shù)函數(shù) Scala 都可以推測(cè)出函數(shù)返回值的類型,但目前來說回溯函數(shù)(函數(shù)調(diào)用自身)還是需要指明返回結(jié)果類型的。

下面在定義個(gè)“沒有”返回結(jié)果的函數(shù)(其它語言可能稱這種無返回值的函數(shù)為程式)。

scala> def greet() = println("hello,world")
greet: ()Unit

greet 函數(shù)的返回值類型為 Unit 表示該函數(shù)不返回任何有意義的值,Unit 類似于 Java 中的 void 類型。這種類型的函數(shù)主要用來獲得函數(shù)的“副作用”,比如本函數(shù)的副作用是打印招呼語。

第四步 編寫 Scala 腳本

Scala 本身是設(shè)計(jì)用來編寫大型應(yīng)用的,但它也可以作為腳本語言來執(zhí)行,腳本為一系列 Scala 表達(dá)式構(gòu)成以完成某個(gè)任務(wù),比如前面的 Hello World 腳本,你也可以使用腳本來實(shí)現(xiàn)一些比如復(fù)制文件,創(chuàng)建目錄之類的任務(wù)。

第五步: 使用 while 配合使用if實(shí)現(xiàn)循環(huán)

下面的代碼使用while實(shí)現(xiàn)一個(gè)循環(huán):

var i=0
while (i < args.length) {
  println (args(i))
  i+=1
}

為了測(cè)試這段代碼,可以將該代碼存成一個(gè)文件,比如 printargs.scala,將該語句作為腳本運(yùn)行,比如在命令行中輸入

scala printargs.scala I like Scala

則顯示:

http://wiki.jikexueyuan.com/project/scala-development-guide/images/8.png" alt="" />

這里要注意的是 Scala 不支持++i,i++ 運(yùn)算符,因此需要使用 i+=1 來加一。 這段代碼看起來和 Java 代碼差不多,實(shí)際上 while 也是一個(gè)函數(shù),你自動(dòng)可以利用 scala 語言的擴(kuò)展性,實(shí)現(xiàn)while 語句,使它看起來和 Scala 語言自帶的關(guān)鍵字一樣調(diào)用。Scala訪問數(shù)組的語法是使用()而非[]。

這里介紹了使用 while 來實(shí)現(xiàn)循環(huán),但這種實(shí)現(xiàn)循環(huán)的方法并不是最好的 Scala 風(fēng)格,在下一步介紹使用一種更好的方法來避免通過索引來枚舉數(shù)組元素。

第六步:使用 foreach和 for 來實(shí)現(xiàn)迭代

第五步使用 while 來實(shí)現(xiàn)循環(huán),和使用 Java 實(shí)現(xiàn)無太大差異,而 Scala 是面向函數(shù)的語言,更好的方法是采用“函數(shù)式“風(fēng)格來編寫代碼。比如上面的循環(huán),使用 foreach 方法如下:

args.foreach(arg => println(arg))

該表達(dá)式,調(diào)用 args 的 foreach 方法,傳入一個(gè)參數(shù),這個(gè)參數(shù)類型也是一個(gè)函數(shù)( lambda 表達(dá)式,和 C# 中概念類似)。這段代碼可以再寫的精簡(jiǎn)些,你可以利用 Scala 支持的縮寫形式,如果一個(gè)函數(shù)只有一個(gè)參數(shù)并且只包含一個(gè)表達(dá)式,那么你無需明確指明參數(shù)。因此上面的代碼可以寫成:

args.foreach( println)

Scala 中也提供了一個(gè)稱為 “for comprehension” 的比 Java 中 for 表達(dá)式功能更強(qiáng)大。“for comprehension” (抱歉找不到合適的中文詞來翻譯這個(gè)術(shù)語,姑且使用 for 表達(dá)式)將在后面介紹,這里先使用 for 來實(shí)現(xiàn)前面的例子:

for (arg <-args)
  println(arg)
上一篇:函數(shù)–閉包下一篇:包對(duì)象