1. 程式人生 > 其它 >四天過完scala語法(第一天)

四天過完scala語法(第一天)

第三章 scala 基礎

1. 宣告值和變數

val:是不可變的,在宣告時就必須被初始化,而且初始化以後就不能再賦值;

var:是可變的,宣告的時候需要進行初始化,初始化以後還可以再次對其賦值。(注意:var變數在宣告的時候也需要初始化)

val myStr = "Hello World!"

注意的是,儘管我們在第1行程式碼的宣告中,沒有給出myStr是String型別,但是,Scala具有“型別推斷”能力,可以自動推斷出變數的型別。

當然,我們也可以顯式宣告變數的型別:

val myStr2 : String = "Hello World!"

需要說明的是,上面的String型別全稱是java.lang.String,也就是說,Scala的字串是由Java的String類來實現的,因此,我們也可以使用java.lang.String來宣告,具體如下:

val myStr3 : java.lang.String = "Hello World!"

但是,為什麼可以不用java.lang.String,而只需要使用String就可以宣告變數呢?這是因為,在每個應用程式中,Scala都會自動新增一些引用,這樣,就相當於在每個程式原始檔的頂端都增加了一行下面的程式碼:

  1. import java.lang._ //java.lang包裡面所有的東西

2. 基本資料型別和操作

Scala的資料型別包括:Byte、Char、Short、Int、Long、Float、Double和Boolean。和Java不同的是,在Scala中,這些型別都是“類”,並且都是包scala的成員,比如,Int的全名是scala.Int。對於字串,Scala用java.lang.String類來表示字串。


這裡要明確什麼是“字面量”?字面量包括整數字面量、浮點數字面量、布林型字面量、字元字面量、字串字面量、符號字面量、函式字面量和元組字面量。舉例如下:

  1. val i = 123 //123就是整數字面量
  2. val i = 3.14 //3.14就是浮點數字面量
  3. val i = true //true就是布林型字面量
  4. val i = 'A' //'A'就是字元字面量
  5. val i = "Hello" //"Hello"就是字串字面量

Scala允許對“字面量”直接執行方法,比如:

  1. 5.toString() //產生字串"5"
  2. "abc".intersect("bcd") //輸出"bc"

上面的intersect()方法用來輸出兩個字串中都存在的字元。

操作符

在Scala中,可以使用加(+)、減(-) 、乘(*) 、除(/) 、餘數(%)等操作符,而且,這些操作符就是方法。例如,5 + 3和(5).+(3)是等價的,也就是說:

a 方法 b
a.方法(b)

上面這二者是等價的。前者是後者的簡寫形式,這裡的+是方法名,是Int類中的一個方法。具體程式碼如下:

  1. scala> val sum1 = 5 + 3 //實際上呼叫了 (5).+(3)
  2. sum1: Int = 8
  3. scala> val sum2 = (5).+(3) //可以發現,寫成方法呼叫的形式,和上面得到相同的結果
  4. sum2: Int = 8

需要注意的是,和Java不同,在Scala中並沒有提供++和--操作符,當需要遞增和遞減時,可以採用如下方式表達:

  1. scala> var i = 5;
  2. i: Int = 5
  3. scala> i += 1 //將i遞增
  4. scala> println(i)
  5. 6

此外,也可以使用關係和邏輯操作,比如,大於(>)、小於(<)、大於等於(>=)和小於等於(<=),會產生Boolean型別的結果。

3. Range

在執行for迴圈時,我們經常會用到數值序列,比如,i的值從1迴圈到5,這時就可以採用Range來實現。Range可以支援建立不同資料型別的數值序列,包括Int、Long、Float、Double、Char、BigInt和BigDecimal等。

在建立Range時,需要給出區間的起點和終點以及步長(預設步長為1)。下面通過幾個例項來介紹:
(1)建立一個從1到5的數值序列,包含區間終點5,步長為1

  1. scala> 1 to 5
  2. res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)

之前我們已經介紹過,在Scala中允許對“字面量”直接執行方法,所以,上面的程式碼,也可以用下面的程式碼來實現:

  1. scala> 1.to(5)
  2. res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)

(2)建立一個從1到5的數值序列,不包含區間終點5,步長為1

  1. scala> 1 until 5
  2. res1: scala.collection.immutable.Range = Range(1, 2, 3, 4)

(3)建立一個從1到10的數值序列,包含區間終點10,步長為2

  1. scala> 1 to 10 by 2
  2. res2: scala.collection.immutable.Range = Range(1, 3, 5, 7, 9)

(4)建立一個Float型別的數值序列,從0.5f到5.9f,步長為0.8f

    1. scala> 0.5f to 5.9f by 0.8f
    2. res3: scala.collection.immutable.NumericRange[Float] = NumericRange(0.5, 1.3, 2.1, 2.8999999, 3.6999998, 4.5, 5.3

4. 列印語句

在Scala程式設計中,經常需要用到列印語句。

print("My name is:")
print("Ziyu")

上述程式碼執行後,會得到連在一起的一行結果,如下:

My name is Ziyu

如果要每次列印後追加一個換行符,實現換行的效果,就要採用println語句,如下:

println("My name is:")
println("Ziyu")

上述程式碼執行後,會得到兩行結果,如下:

My name is
Ziyu

如果要列印整型變數的值,可以使用下面語句:

val i = 7
println(i)

此外,Scala還帶有C語言風格的格式化字串的printf函式:

val i = 5;
val j = 8;
printf("My name is %s. I hava %d apples and %d eggs.\n","Ziyu",i,j)

上面語句執行後會得到如下結果:

My name is Ziyu. I hava 5 apples and 8 eggs.

更多關於printf函式的使用方法,讀者可以參考C語言書籍。

總結,scala可以使用 print, println, printf。

5. 讀寫檔案

 

Scala需要使用java.io.PrintWriter實現把資料寫入到文字檔案。
假設當前正使用使用者名稱hadoop登入Linux系統,開啟Scala直譯器進入命令提示符狀態後,輸入以下程式碼:

  1. scala> import java.io.PrintWriter
  2. import java.io.PrintWriter //這行是Scala直譯器執行上面語句後返回的結果
  3. scala> val out = new PrintWriter("output.txt")
  4. out: java.io.PrintWriter = java.io.PrintWriter@25641d39 //這行是Scala直譯器執行上面語句後返回的結果
  5. scala> for (i <- 1 to 5) out.println(i)
  6. scala> out.close()
scala

上面程式碼中,new PrintWriter("output.txt")中只給出了檔名,並沒有給出檔案路徑,採用相對路徑,這時,檔案就會被儲存到啟動Scala REPL時的當前目錄下。比如,如果我們是進入“/home/hadoop”使用者目錄,在這個目錄下啟動進入了Scala REPL互動式執行環境,則上面程式碼執行結束後,可以在hadoop使用者的工作目錄“/home/hadoop/”下找到新生成的這個output.txt檔案。為了檢視這個檔案,我們可以在當前“終端”視窗的基礎上,再新建一個終端視窗,你可以在當前終端視窗的左上角看到一個選單,點選“終端”,選擇“新建終端”,就可以開啟第二個命令列終端視窗(用來檢視檔案)。
現在,讓我們切換到第二個終端視窗,然後,輸入下面命令進入到hadoop使用者的工作目錄,並顯示該目錄下的所有檔案和資料夾資訊:

  1. cd ~
  2. ls
Shell 命令

"~"就表示當前使用者的工作目錄,對於hadoop使用者而言,就是“/home/hadoop/”目錄。
上面命令執行後,就可以發現,“/home/hadoop/”目錄下有個新生成的這個output.txt檔案,下面使用cat命令檢視該檔案內容:

  1. cat output.txt
Shell 命令

需要注意的是,必須要執行out.close()語句,才會看到output.txt檔案被生成,如果沒有執行out.close()語句,我們就無法看到生成的output.txt檔案。
如果我們想把檔案儲存到一個指定的目錄下,就需要給出檔案路徑,程式碼如下:

  1. scala> import java.io.PrintWriter
  2. import java.io.PrintWriter //這行是Scala直譯器執行上面語句後返回的結果
  3. scala> val out = new PrintWriter("/usr/local/scala/mycode/output.txt")
  4. out: java.io.PrintWriter = java.io.PrintWriter@25641d39 //這行是Scala直譯器執行上面語句後返回的結果
  5. scala> for (i <- 1 to 5) out.println(i)
  6. scala> out.close()

上述過程執行結束後,就可以到“/usr/local/scala/mycode/”這個目錄下找到output.txt檔案。

讀取文字檔案中的行

可以使用Scala.io.Source的getLines方法實現對檔案中所有行的讀取。
仍然假設當前是用hadoop使用者登入了Linux系統,並且使用scala命令啟動了Scala直譯器,現在,我們要把上面剛生成的、在hadoop使用者工作目錄下的output.txt檔案讀取出來,下面給出了完整的讀取檔案例項程式碼:

    1. scala> import scala.io.Source
    2. import scala.io.Source //這行是Scala直譯器執行上面語句後返回的結果
    3. scala> val inputFile = Source.fromFile("output.txt")
    4. inputFile: scala.io.BufferedSource = non-empty iterator //這行是Scala直譯器執行上面語句後返回的結果
    5. scala> val lines = inputFile.getLines //返回的結果是一個迭代器
    6. lines: Iterator[String] = non-empty iterator //這行是Scala直譯器執行上面語句後返回的結果
    7. scala> for (line <- lines) println(line)
    8. 1
    9. 2
    10. 3
    11. 4
    12. 5