第4章 Scala程序流程控制

4.1 程序流程控制分類

① 順序控制

② 分支控制

③ 循環控制

4.2 順序控制

4.2.1順序控制介紹

程序從上到下逐行地執行,中間沒有任何判斷和跳轉。

4.2.2 順序控制舉例和注意事項

Scala中定義變量時採用合法的前向引用。如:

def main(args : Array[String]) : Unit = {
    var num1 = 12
    var num2 = num1 + 2
}

錯誤形式:

def main(args : Array[String]) : Unit = {
    var num2 = num1 + 2
    var num1 = 12
}

4.3 分支控制if-else

4.3.1 分支控制if-else介紹

讓程序有選擇的的執行,分支控制有三種:

單分支

雙分支

多分支

4.3.2 單分支

基本語法

if (條件表達式) {

執行代碼塊

}

說明:當條件表達式爲ture 時,就會執行 { } 的代碼。

示例代碼

object IfDemo {
    def main(args: Array[String]): Unit = {
        val age = 20
        if (age > 18) {
            println("age > 18")
        }

    }
}

4.3.3 雙分支

基本語法

if (條件表達式) {

    執行代碼塊1

} else {

    執行代碼塊2

}

說明:當條件表達式成立,即執行代碼塊1,否則執行代碼塊2.

示例代碼

需求

判斷一個年份是否是閏年,閏年的條件是符合下面二者之一:(1)年份能被4整除,但不能被100整除;(2)能被400整除

import scala.io.StdIn

object TestControl {

  def main(args: Array[String]): Unit = {

    println("year")
    val year = StdIn.readInt()
    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
      println("是閏年")
    } else {
      println("不是閏年")
    }

  }
}

4.3.4 多分支

基本語法

if (條件表達式1) {

    執行代碼塊1

}else if (條件表達式2) {

    執行代碼塊2

}……

else {

    執行代碼塊n

}

示例代碼

object IfDemo3 {
  def main(args: Array[String]): Unit = {
    
    var grade = 90
    if (grade == 100) {
      println("獎勵一輛BMW")
    } else if (grade > 80) {
      println("獎勵一臺iphone7plus")
    } else if (grade >= 60) {
      println("獎勵一個 iPad")
    } else {
      println("no")
    }

  }
}

4.3.5 分支控制if-else 注意事項

① 如果大括號{}內的邏輯代碼只有一行,大括號可以省略, 這點和java 的規定一樣。

② Scala中任意表達式都是有返回值的,也就意味着if else表達式其實是有返回結果的,具體返回結果的值取決於滿足條件的代碼體的最後一行內容

object Test {
  def main(args: Array[String]): Unit = {
    
    var sumVal = 10
    var result = if (sumVal == 0) {
      println("ok") // 此處爲滿足條件邏輯的最後一行內容,打印語句是沒有返回值的
    } else {
      "nook" //此處爲不滿足條件邏輯的最後一行內容,此處返回值爲字符串String
    }
    //說明明:
    //1. 因爲Scala在編譯期間無法知道程序的邏輯是滿足或不滿足,所以無法推斷出result變量的具體類型,
    // 所以就設定爲Any類型(所有類型的公共超類型)
    //2. 如果if-else 的兩條分支結果都是確定的並且相同的數據類型,那麼result變量的類型就是直接確定了.
    //3. sumVal = 10 result = nook, sumVal = 0 result = ()類似java中的void
    
    println("res=" + result)

  }
}

③ Scala中是沒有三元運算符,因爲可以這樣簡寫

val result = if (flg) 1 else 0

4.3.6 嵌套分支

需求:

出票系統:根據淡旺季的月份和年齡,打印票價

4_10 旺季:

成人(18-60):60

兒童(<18):半價

老人(>60):1/3

 

淡季:

成人:40

其他:20

import scala.io.StdIn

object TestControl {
  def main(args: Array[String]): Unit = {
    
    println("month:");
    val month = StdIn.readInt()
    println("age:");
    val age = StdIn.readInt()
    if (month >= 4 && month <= 10) {
      //旺季
      if (age > 60) {
        println("¥20");
      } else if (age >= 18) {
        println("¥60");
      } else {
        println("¥30");
      }
    } else {
      //淡季
      if (age >= 18 && age < 60) {
        println("¥40");
      } else {
        println("¥20");
      }
    }

  }
}

4.4 for循環控制

4.4.1 基本介紹

Scala 也爲for 循環這一常見的控制結構提供了非常多的特性,這些for 循環的特性被稱爲for 推導式(for comprehension)或for 表達式(for expression)

4.4.2 範圍數據循環方式

基本案例

object ForTest {
  def main(args: Array[String]): Unit = {

    for (i <- 1 to 3) { //[1,3]
      print(i + " ") //1 2 3
    }
    
    println()
    
    for (j <- 1 until 3) { //[1,3) 顧頭不顧腚
      print(j + " ") // 1 2
    }

  }
}

4.4.3 循環守衛

基本案例

object ForTest {
  def main(args: Array[String]): Unit = {
    
    for (i <- 1 to 3 if i != 2) {
      print(i + " ") //1 3
    }

    println()

  }
}

說明

① 循環守衛,即循環保護式(也稱條件判斷式,守衛)。保護式爲true則進入循環體內部,爲false則跳過,類似於continue

② 上面的代碼等價

object ForTest {
  def main(args: Array[String]): Unit = {
    
    for (i <- 1 to 3) {
      if (i != 2) {
        println(i + "")
      }
    }

  }
}

4.4.4 引入變量

基本案例

for(i <- 1 to 3; j = 4 - i) {
    print(j + " ")
}

說明

① 沒有關鍵字,所以範圍後一定要加;來隔斷邏輯

② 上面的代碼等價

for (i <- 1 to 3) {
    val j = 4-i
    print (j + "")
}

4.4.5 嵌套循環

基本案例

for(i <- 1 to 3; j <- 1 to 3) {
    println(" i =" + i + " j = " + j)
}

說明

① 沒有關鍵字,所以範圍後一定要加;來隔斷邏輯

② 上面的代碼等價

​for (i <- 1 to 3) {
    for (j <- 1 to 3) {
        println(i + " " + j + " ")
    }
}

4.4.6 循環返回值

基本案例

val res = for(i <- 1 to 10) yield i
println(res)

說明

將遍歷過程中處理的結果返回到一個新Vector集合中,使用yield關鍵字

4.4.7 使用{}代替()

基本案例

for(i <- 1 to 3; j = i * 2) {
    println(" i= " + i + " j= " + j)
}

可以寫成

for{
    i <- 1 to 3
    j = i * 2} {
        println(" i= " + i + " j= " + j)
}

說明

① {}和()對於for表達式來說都可以

② for 推導式有一個不成文的約定:當for 推導式僅包含單一表達式時使用圓括號,當其包含多個表達式時使用大括號

③ 當使用{} 來換行寫表達式時,分號就不用寫了

4.4.8 控制步長

object ForTest {

  def main(args: Array[String]): Unit = {
    
    //如果要倒敘遍歷 Range(3,1,-1)就可以了
    //Range的範圍和until 的規則一樣
    
    println("for Range(開始,結束,步長) :")
    for (i <- Range(1, 3, 2)) {
      println(i + " ") //1
    }

  }
}
object ForTest {
  def main(args: Array[String]): Unit = {
    
    for (i <- 1 until 7 if (i % 4 == 1)) {
      println(i) //1 5
    }
    
  }
}

4.5 while循環

4.5.1 基本語法

循環變量初始化

while (循環條件) {

    循環體(語句)

    循環變量迭代

}

4.5.2 注意事項和細節說明

① 循環條件是返回一個布爾值的表達式

② while循環是先判斷再執行語句

③ 與If語句不同,While語句本身沒有值,即整個While語句的結果是Unit類型的()

④ 因爲while中沒有返回值,所以當要用該語句來計算並返回結果時,就不可避免的使用變量 ,而變量需要聲明在while循環的外部,那麼就等同於循環的內部對外部的變量造成了影響,所以不推薦使用,而是推薦使用for循環。

4.5.3 示例代碼

object WhileTest {
  def main(args: Array[String]): Unit = {

    //打印1—100之間所有能被3整除的數
    var i = 1
    var max = 100
    while (i <= max) {
      if (i % 3 == 0) {
        println(i)
      }
      i += 1
    }

  }
}

4.6 do..while循環控制

4.6.1 基本語法

循環變量初始化;

do{

    循環體(語句)

    循環變量迭代

} while(循環條件)

4.6.2 示例代碼

object DoWhileTest {
  def main(args: Array[String]): Unit = {

    //計算1—100的和
    var i = 1
    var sum = 0
    do {
      //循環操作
      //sum=sum+i;
      sum += i
      i += 1
    } while (i <= 100)

    println(sum)
    
  }
}

4.7 while循環的中斷

4.7.1 基本說明

Scala內置控制結構特地去掉了break和continue,是爲了更好的適應函數化編程,推薦使用函數式的風格解決break和contine的功能,而不是一個關鍵字。

import util.control.Breaks._

object WhileBreak {
  def main(args: Array[String]): Unit = {
    
    var n = 1
    //breakable()函數
    //說明
    //1. breakable 是一個高階函數:可以接收函數的函數就是高階函數(後面詳解)
    //2. def breakable(op: => Unit) {
    // try {
    // op
    // } catch {
    // case ex: BreakControl =>
    // if (ex ne breakException) throw ex
    // }
    // }
    // (1) op: => Unit 表示接收的參數是一個沒有輸入,也沒有返回值的函數
    // (2) 即可以簡單理解可以接收一段代碼塊
    // 3. breakable 對break()拋出的異常做了處理,代碼就繼續執行
    // 4. 當我們傳入的是代碼塊,scala程序員會將() 改成{}

    breakable {
      while (n <= 20) {
        n += 1
        println("n=" + n)
        if (n == 18) {
          //中斷while
          //說明
          //1. 在scala中使用函數式的break函數中斷循環
          //2. def break(): Nothing = { throw breakException }
          break()
        }
      }
    }
    
    println("ok~~")
    
    //注意break函數,可以使用在for或者do..while
    breakable {
      for (i <- 1 to 100) {
        println("i=" + i)
        if (i == 20) {
          break()
        }
      }
    }
    
    println("ok2~~~~")
    
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章