Scala入門到放棄——變量、類型、條件分支、循環(二)

三、變量和類型

常用類型

和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是所有類型的超類型,也稱爲頂級類型。它定義了一些通用的方法如equalshashCodetoStringAny有兩個直接子類:AnyValAnyRef
  • AnyVal代表值類型。有9個預定義的非空的值類型分別是:DoubleFloatLongIntShortByteCharUnitBooleanUnit(類似於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條件){
  // 循環體
}

如:求1100數值之和
// 控制檯輸入求和值
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條件)

如:求1100數值之和
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中沒有提供breakcontinue關鍵詞來退出循環,可以使用Breaks對象中的break方法終止循環

import scala.util.control.Breaks._
breakable {
  for (n <- 1 to 10) {
    if (n == 5) break
    println(n)
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章