【Kotlin】第3課-迴圈

迴圈是程式流程控制的一環,用來重複執行相似的工作。Kotlin 提供的迴圈種類與 Java 相同,有「while」、「do-while」與「for」。此外 Kotlin 也提供了範圍敘述及迴圈標籤的語法,讓可讀性更佳。本文就來認識它們。

一、while 迴圈

Kotlin 的 while 迴圈跟 Java 一模一樣,每一次的循環之前會檢查條件式,筆者在此就簡單帶過。下面的範例是計算存款與利息的總和,情境是本金10萬元,利率2%,每年複利一次,存5年。

var money = 100000.0
val rate = 0.02
val year = 5

var i = 1
while (i <= year) {
money += money * rate
i++
}

println(money)


二、do-while 迴圈

Kotlin 的 do-while 迴圈也與 Java 相同。它至少會執行一次,且在每次的循環後才檢查條件式。筆者這裡也簡單帶過,情境沿用第一節存款利息的範例。

var money = 100000.0
val rate = 0.02
val year = 5

var i = 1
do {
money += money * rate
i++
} while (i <= year)

println(money)


三、範圍

在學習 for 迴圈前,需要先認識 Kotlin 的「範圍」敘述。Java 的 for 迴圈用了如 int i=0; i<10; i=i+1 的語法,使得每次循環的 i 值都不同。而範圍敘述融合了這三項,執行迴圈時透過類似 for each 的語法給予 i 值。

範圍類似數學上用大於、小於和等於定義的「區間」,只是加入了大小順序的概念。它也像陣列一樣可以逐一取出元素(迭代)。以下介紹相關語法的使用方式。

  1. ..
    用於遞增,寫法如「1..5」
    順序為1、2、3、4、5
  2. downTo
    用於遞減,寫法如「5 downTo 1」
    順序為5、4、3、2、1
  3. until
    用於遞增,寫法如「1 until 5」
    順序為1、2、3、4
  4. step
    搭配以上語法,可以改變遞增減的量,寫法如「1..5 step 2」
    順序為1、3、5

Kotlin 的 for 迴圈需要搭配「範圍」來使用。第四節將用程式碼示範,讀者會更清楚它們的效果。

四、for 迴圈

Kotlin 的 for 迴圈,寫法跟 Java 有一些差別。它會透過「in」語法,按照順序讀取該範圍內的值,賦予給迴圈的臨時變數,與 for each 的概念相似。

以下是遞增迴圈的範例,相關的語法包含「..」、「until」與「step」。

// 印出1、2、3、4、5
for (i in 1..5) {
println(i)
}

// 範圍到5之前,印出1、2、3、4
for (i in 1 until 5) {
println(i)
}

// 間隔2,印出1、3、5
for (i in 1..5 step 2) {
println(i)
}

// 範圍到9之前,間隔3,印出1、4、7
for (i in 1 until 9 step 3) {
println(i)
}

以下是遞減迴圈的範例,相關的語法包含「downTo」與「step」。

// 印出5、4、3、2、1
for (i in 5 downTo 1) {
println(i)
}

// 間隔2,印出5、3、1
for (i in 5 downTo 1 step 2) {
println(i)
}

若想透過自己的變數來定義 for 迴圈的範圍,可以寫成如下。

val length = 5

// 印出0、1、2、3、4
for (i in 0 until length) {
println(i)
}


五、跳出或循環指定的迴圈

有時我們會需要一層以上的迴圈來完成工作,例如在二維陣列中走訪元素。但若在內層迴圈執行到一半時就想結束,並繼續外層迴圈的新循環或是再跳出,可能會宣告一個作為旗標(flag)用途的變數來處理。

根據這種做法,以下的程式是累計九九乘法表的乘積,按照1x1、1x2、1x3、…、2x1的順序持續累計。若加總值剛好遇到24的倍數,就把目前的值印出來,並中止該被乘數的累計,轉往下一個。

var total = 0

for (i in 1..9) {
var flag = false

for (j in 1..9) {
total += i * j

flag = (total % 24 == 0)
if (flag) {
println(total)
break
}
}

if (flag) {
continue
}

println("第${i}部份已結束")
}

若透過 flag 變數的做法,會有點麻煩,程式碼也長了一些。但 Kotlin 提供了特別的語法,我們可以給迴圈加上「標籤」(Label),並在內部指定要「break」或「continue」哪一個迴圈。因此上面的範例能改寫成如下。

var total = 0

multiplicand@ for (i in 1..9) {
for (j in 1..9) {
total += i * j

if (total % 24 == 0) {
println(total)
continue@multiplicand
}
}

println("第${i}部份已結束")
}

透過「@」符號,對外層迴圈添加標籤,筆者取名為 multiplicand(被乘數)。接著在內部使用 break 或 continue 語法時,再簡單地加上迴圈標籤,就能跳離或循環指定的迴圈,十分方便。在第4課的第四節,也會以二維陣列為對象來使用這種標籤,讀者可以參考。

除了 for 迴圈,while 與 do-while 迴圈也能利用這種添加標籤的方式。

上一篇:【Kotlin】第2課-條件判斷

下一篇:【Kotlin】第4課-陣列(Array)

留言