Scala開發教程(2): 起步Scala

在詳細介紹Scala編程之前,我們先用兩篇文章給你一個Scala的整體印象,更重要的是讓你開始寫代碼。強烈建議初學Scala編程者編譯運行本教程的每個示例。如果你是個非常有經驗的程序員,那麼前面的這兩篇文章可以使得你或的足夠的知識開始編寫一些實用的程序。

第一步 ,學習使用交互式Scala解釋器
開始使用Scala的最簡單的方式是使用交互式Scala解釋器,只要輸入Scala表達式,Scala解釋器會立即解釋執行該語句並輸出結果。當然你也可以使用如Scala IDE或IntelliJ IDEA集成開發環境。不過本教程開始還是以這種交互式Scala解釋器爲主。
使用Scala解釋器,首先你需要下載安裝Scala運行環境。 然後再命令行輸入scala ,則進入scala 解釋器,下圖爲Linux環境下scala 解釋器界面:你可以使用:help 命令列出一些常用的Scala解釋器命令,退出Scala解釋器,輸入

1 :quit

20131004005

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

1 res0: Int = 3

這行顯示包括:

  • 一個由Scala解釋器自動生成的變量名或者由你指定的變量名用來指向計算出來的結果(比如 res0 代表 result0變量)
  • 一個冒號,後面緊跟個變量類型比如Int
  • 一個等於號
  • 計算結果,本例爲1+2的結果3

resX 變量名可以用在之後的表達式中,比如 此時res0=3,如果輸入 res0 *3 ,則顯示 res1: Int =9

20131004006

第二步:定義一些變量
Scala 定義了兩種類型的變量 val 和 var ,val 類似於Java中的final 變量,一旦初始化之後,不可以重新複製(我們可以稱它爲常變量)。而var 類似於一般的非final變量。可以任意重新賦值。
比如定義一個字符串常變量:

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

這個表達式定義了一個msg變量,爲字符串常量。它的類型爲 string (java.lang.string). 可以看到我們在定義這個變量時並不需要像Java一樣定義其類型,Scala 可以根據賦值的內容推算出變量的類型。這在Scala語言中成爲“type inference”。當然如果你願意,你也可以採用和Java一樣的方法,明確指定變量的類型,如

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

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

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

第三步:定義一些函數
Scala既是面向對象的編程語言,也是面向函數的編程語言,因此函數在Scala語言中的地位和類是同等第一位的。下面的代碼定義了一個簡單的函數求兩個值的最大值:

1 scala> def max(x:Int,y:Int) : Int ={
2      if (x >y) x
3      else
4      | y
5      | }
6 max: (x: Int, y: Int)Int

Scala函數以def定義,然後是函數的名稱(如max),然後是以逗號分隔的參數。Scala中變量類型是放在參數和變量的後面,以“:”隔開。這種做的一個好處是便與”type inference”。剛開始有些不習慣(如果你是Pascal程序員會覺的很親切)。同樣如果函數需要返回值,它的類型也是定義在參數的後面(實際上每個Scala函數都有返回值,只是有些返回值類型爲Unit,類似爲void類型)。
此外每個Scala表達式都有返回結果(這一點和Java,C#等語言不同),比如Scala的 if else 語句也是有返回值的,因此函數返回結果無需使用return語句。實際上在Scala代碼應當儘量避免使用return語句。函數的最後一個表達式的值就可以作爲函數的結果作爲返回值。
同樣由於Scala的”type inference”特點,本例其實無需指定返回值的類型。對於大多數函數Scala都可以推測出函數返回值的類型,但目前來說回溯函數(函數調用自身)還是需要指明返回結果類型的。
下面在定義個“沒有”返回結果的函數(其它語言可能稱這種無返回值的函數爲程式)。

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

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

第四步 編寫Scala腳本
Scala本身是設計用來編寫大型應用的,但它也可以作爲腳本語言來執行,腳本爲一系列Scala表達式構成以完成某個任務,比如前面的Hello World 腳本,你也可以使用腳本來實現一些比如複製文件,創建目錄之類的任務。

第五步: 使用while 配合使用if實現循環

下面的代碼使用while實現一個循環:

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

爲了測試這段代碼,可以將該代碼存成一個文件,比如printargs.scala ,將該語句作爲腳本運行,比如在命令行中輸入

scala printargs.scala I like Scala

則顯示:

20131004007

這裏要注意的是Scala不支持 ++i,i++ 運算符,因此需要使用i+=1 來加一。 這段代碼看起來和Java代碼差不多,實際上while 也是一個函數,你自動可以利用scala語言的擴展性,實現while 語句,使它看起來和Scala語言自帶的關鍵字一樣調用。
Scala訪問數組的語法是使用()而非[].

這裏介紹了使用while來實現循環,但這種實現循環的方法並不是最好的Scala風格,在下一步介紹使用一種更好的方法來避免通過索引來枚舉數組元素。

第六步:使用 foreach和 for 來實現迭代
第五步使用while來實現循環,和使用Java實現無太大差異,而Scala是面向函數的語言,更好的方法是採用“函數式“風格來編寫代碼。比如上面的循環,使用foreach方法如下:

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

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

1 args.foreach( println)

Scala中也提供了一個稱爲“for comprehension”的比Java中for表達式功能更強大。“for comprehension”(抱歉找不到合適的中文詞來翻譯這個術語,姑且使用for表達式)將在後面介紹,這裏先使用for來實現前面的例子:

1 for (arg <-args)
2   println(arg)
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章