三、變量和類型
常用類型
和Java一樣,Scala中也有7種數值類型:Byte、Short、Int、Long、Double、Float、Char,以及1個Boolean類型。跟Java不同的是,這些類型都是類,歸屬於scala.*
包。還有一種常用類型爲java.lang.String
用以聲明字符串
表達式
表達式是可計算的語句。如:
1 + 1
你可以使用println
來輸出表達式的結果。
// println 打印表達式的值 換行
// print 打印表達式的值 不換行
// 引用表達式的值打印
println(1) // 1
println(1 + 1) // 2
println("Hello!") // Hello!
println("Hello," + " world!") // Hello, world!
聲明變量
除了可以重新賦值,變量和常量類似。你可以使用var
關鍵字來定義一個變量。
var x = 1 + 1
x = 3 // This compiles because "x" is declared with the "var" keyword.
println(x * x) // 9
注意:scala類型可以被推斷,或者你也可以顯示地聲明類型,語法
var x : Int = 10
聲明常量(推薦)
你可以使用val
關鍵字來給表達式的結果命名。
val x = 1 + 1
println(x) // 2
x = 3 // This does not compile.
類型轉換
值類型可以按照下面的方向進行轉換:
例如:
val x: Long = 987654321
val y: Float = x // 9.8765434E8 (note that some precision is lost in this case)
val face: Char = '☺'
val number: Int = face // 9786
轉換是單向,下面這樣寫將不會通過編譯。
val x: Long = 987654321
val y: Float = x // 9.8765434E8
val z: Long = y // Does not conform
你可以將一個類型轉換爲子類型
運算符
-
算術運算符:
+、-、*、/、%
-
關係運算符:
==、!=、>、<、>=、<=
-
邏輯運算符:
&&、||、!
-
位運算符:
&(按位與)、|(按位或)、^(異或)、~(取反)、<<、>>、>>>(無符號)
2 00000010 3 00000011 2&3=2 00000010 & 同時爲1 結果爲1 不同爲0 2|3=3 00000011 | 有一個爲1 結果爲1 不同爲0 2^3=1 00000001 ^ 相同爲0,不同爲1 ~2=-3 11111101 2<<1=4 00000100 二進制 向左移動 n位 2>>1=1 >>>
-
賦值運算符:
=
注意:在Scala中,運算符即是方法。
10 + 1
可以寫成10.+(1)
Scala類型層次結構【重點】
在Scala中,所有的值都有類型,包括數值和函數。下圖闡述了類型層次結構的一個子集。
Any
是所有類型的超類型,也稱爲頂級類型。它定義了一些通用的方法如equals
、hashCode
和toString
。Any
有兩個直接子類:AnyVal
和AnyRef
。AnyVal
代表值類型。有9個預定義的非空的值類型分別是:Double
、Float
、Long
、Int
、Short
、Byte
、Char
、Unit
和Boolean
。Unit
(類似於java中的void
)是不帶任何意義的值類型,它僅有一個實例可以像這樣聲明:()
。所有的函數必須有返回,所以說有時候Unit
也是有用的返回類型。AnyRef
代表引用類型。所有非值類型都被定義爲引用類型。在Scala中,每個用戶自定義的類型都是AnyRef
的子類型。如果Scala被應用在Java的運行環境中,AnyRef
相當於java.lang.Object
。Nothing
是所有類型的子類型,也稱爲底部類型。沒有一個值是Nothing
類型的。它的用途之一是給出非正常終止的信號,如拋出異常、程序退出或者一個無限循環(可以理解爲它是一個不對值進行定義的表達式的類型,或者是一個不能正常返回的方法)。Null
是所有引用類型的子類型(即AnyRef
的任意子類型)。它有一個單例值由關鍵字null
所定義。Null
主要是使得Scala滿足和其他JVM語言的互操作性,但是幾乎不應該在Scala代碼中使用。我們將在後面的章節中介紹null
的替代方案。
這裏有一個例子,說明了字符串、整型、布爾值和函數都是對象,這一點和其他對象一樣:
val list: List[Any] = List(
"a string",
732, // an integer
'c', // a character
true, // a boolean value
() => "an anonymous function returning a string"
)
list.foreach(element => println(element))
這裏定義了一個類型List<Any>
的變量list
。這個列表裏由多種類型進行初始化,但是它們都是scala.Any
的實例,所以可以把它們加入到列表中。
下面是程序的輸出:
a string
732
c
true
<function>
四、條件分支
if(布爾表達式 1){
// 如果布爾表達式 1 爲 true 則執行該語句塊
}else if(布爾表達式 2){
// 如果布爾表達式 2 爲 true 則執行該語句塊
}else if(布爾表達式 3){
// 如果布爾表達式 3 爲 true 則執行該語句塊
}else {
// 如果以上條件都爲 false 執行該語句塊
}
if條件分支
如:
if ( n1 > 0) true
if…else條件分支
如:
val result = if ( n1 > 0) true else false
if…else if … else條件分支
val result = if (n1 > 0) 1
else if(n1 == 0) 0
else -1
注意:
- 代碼塊中只有一行內容,可以省略
{}
,如有多行代碼需用{}
- 代碼塊的最後一個表達式的值就是塊的值
- scala中沒有switch語句,不過它有一個強大很多的模式匹配,後續介紹
五、循環
Scala的循環類似於Java的循環
while循環
while(boolean條件){
// 循環體
}
如:求1到100數值之和
// 控制檯輸入求和值
val input : String = readLine("請輸入:")
var num = input.toInt
var sum = 0
while(num > 0){
sum = sum + num
num = num - 1
}
print(sum)
Note : scala中沒有
++
和--
,可以使用+=1
或-=1
替換
do … while…循環
do{
//循環體
}while(boolean條件)
如:求1到100數值之和
do {
sum = sum.+(num)
num = num - 1
} while (num > 0)
print(sum)
for循環
Scala沒有與Java for循環直接對應的結構,語法如下:
// m to n ,返回m到n(包含m)的Range
for (n <- 1 to 100) {
sum = sum + n
}
print(sum)
// m until n ,返回m到n(不包含m)的Range
for (n <- 1 until 100) {
sum = sum + n
}
print(sum)
嵌套for循環
如:九九乘法表
// 傳統方式
for (m <- 1 to 9) {
for (n <- 1 to m) {
print(s"$m*$n=" + m * n + "\t")
if (m == n) println
}
}
// 推薦方式:多層循環用”;“分隔
for (m <- 1 to 9; n <- 1 to m) {
print(s"$m*$n=" + m * n + "\t")
if (m == n) println
}
for遍歷集合
val list = List[String]("Hello World", "Hello Hadoop")
for (str <- list) {
println(str)
}
for循環過濾(if守衛)
if作爲for守衛語句能實現過濾的效果,顯著地降低循環次數,並且更易讀,如下:
for (n <- 1 to 10 if n % 2 == 0 if n > 5) {
println(s"$n")
}
// 6 8 10
yield
for 循環中的 yield 會把當前的元素記下來,保存在集合中,循環結束後將返回該集合
- 針對每一次 for 循環的迭代, yield 會產生一個值,被循環記錄下來 (內部實現上,像是一個緩衝區).
- 當循環結束後, 會返回所有 yield 的值組成的集合.
- 返回集合的類型與被遍歷的集合類型是一致的.
val result = for (n <- 1 to 10 if n % 2 == 1 if n != 5) yield n * 2
println(result)
//Vector(2, 6, 14, 18)
// 如果您願意:也可以將生成器、守衛和定義包含在花括號中,並以換行的方式分隔
val result = for {n <- 1 to 10
if n % 2 == 1
if n != 5}yield n * 2
println(result)
Break
Scala中沒有提供break和continue關鍵詞來退出循環,可以使用Breaks對象中的break方法終止循環
import scala.util.control.Breaks._
breakable {
for (n <- 1 to 10) {
if (n == 5) break
println(n)
}
}