[Day 04] 遠征 Kotlin × 流程控制
此篇將介紹 Kotlin 在流程控制相關語法與特性,在 Kotlin 世界中,條件運算式、迴圈使用方式與其他程式語言相似,這邊快速帶大家了解在 Kotlin 中如何操作。
條件判斷
1. if..else 操作
在專案開發中,我們經常會使用到條件判斷來處理邏輯問題,我們可以直接利用下面範例來觀看 Kotlin 在 if..else
的操作,參考如下:
範例是當我們輸入分數(0-100)時,程式會依據所輸入的分數輸出對應的訊息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| fun main() { print("請輸入分數:") val score: Int = readLine()!!.toInt()
if (score == 100) { println("恭喜考滿分") } else if (score >= 60) { println("恭喜及格") } else if (score >= 0) { println("再接再勵") } else { println("數值必須介於 0 - 100 之間") } }
|
備註: !!
操作符號為非空斷言(Not-null assertion operator)
,表示我們認為輸入的數值不會是空值,若為空值則會立即出現錯誤狀況,而假如我們不使用 !!
操作符號時,Intellij 編輯器會告訴我們轉型會有錯誤,可參考下圖實際狀況:

而與其他語言相比,Kotlin 比較特別的是條件判斷式可根據條件同時進行變數賦值,我們將上面範例改為以下程式:
此範例我們改變上面範例,使用判斷式賦值方法將分數所對應的回應字串回傳給 output
變數,再印出結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| fun main() { print("請輸入分數:") val score: Int = readLine()!!.toInt() val output: String = if (score == 100) "恭喜考滿分" else if (score >= 60) "恭喜及格" else if (score >= 0) "再接再勵" else "成績輸入錯誤" println(output) }
|
2. When 運算式
Kotlin 與其他程式語言比較不同的還有 when
運算式, 在 Kotlin 中,沒有提供其他語言常見的 switch
表達式,而是提供 when
表達式,when
是 Kotlin 的另一個控制流程語法,允許開發者編寫條件式,當滿足某個條件時執行對應程式碼,語法上非常簡潔,條件與執行程式用 →
箭頭符號語法進行配對,此方法適合三到四個流程情況使用,範例如下:
此範例先定義一個 score
變數,再利用 when
表達式進行分數判斷,再回傳對應的訊息,此部份記得此表達式與傳統 switch
不同,when
在條件結束時不需要加上 break
1 2 3 4 5 6 7 8 9 10 11 12 13
| fun main() { print("請輸入分數:") val score: Int = readLine()!!.toInt() val comment: String = when (score) { 100 -> "恭喜滿分" in 60..99 -> "恭喜及格" in 0..60 -> "再接再勵" else -> "分數輸入錯誤" } println(comment) }
|
when
也可以同時多條件判斷,我們試著將上面範例修改為以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| fun main() { print("請輸入分數:") val score: Int = readLine()!!.toInt() val comment: String = when (score) { 100 -> "恭喜滿分" in 60..99 -> { if (score > 80) { "表現優良" } else { "恭喜及格" } } in 0..60 -> "再接再勵" else -> "分數輸入錯誤" } println(comment) }
|
3. Elvis 語法進行null 判斷
Kotlin 還有提供一個簡潔的語法-Elvis
,在實務開發中,我們經常會遇到需要判斷該變數目前是否為 null
的情況,若為 null
,則有預設值進行替代或拋出錯誤提醒,原先情況我們可能會如下範例進行撰寫:
1 2 3 4 5 6 7 8 9 10
| fun main() { val username: String? = "Devin" val usernameLength: Int = if (username == null) { 0 } else { username.length } println(usernameLength) }
|
而 Kotlin 提供 elvis
語法,可以簡單處理這種情況:
1 2 3 4 5 6 7 8 9 10 11
| fun main() { val username: String? = null val usernameLength: Int = username?.length ?: 0 println(usernameLength)
val password: String? = null val passwordLength: Int = password?.length ?: throw IllegalArgumentException("資料為 null") println(passwordLength) }
|
使用 ?:
即可檢查對應的值是否為 null
,若為否,則回傳右邊的數值,此數值若開發者不想賦予任何值,也可以使用 return
回傳
1 2 3
| val username: String? = "Devin" val usernameLength: Int = username?.length ?: return println(usernameLength)
|
迴圈使用
迴圈是程式依據設定的條件進行重複工作,當條件為真就持續進行,反之就結束,而 Kotlin 在迴圈方法上提供與Java 相同,都有 for
、while
、 do while
等方法,其中 Kotlin 迴圈操作的方式非常像 Python,如下範例所示 - 利用 for
迴圈將集合內所有元素逐步印出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| val names = listOf("Anne", "Peter", "Jeff") for (name in names) { println(name) }
val number = 0 while (number < 10) { println(number) number++ }
val doorPassword = "20200913" var keyInAmount= 0 do { println("請輸入密碼進門") val password = readLine()!! keyInAmount++ } while (password != doorPassword && keyInAmount < 3)
|
Kotlin 也提供 Ranges
表達式可讓開發者快速建立兩個值的區間,一般通常會與in
、in!
一起使用,其餘操作如下說明與實作範例,建議閱讀朋友可以直接:
..
操作符號表示為數值區間,例如 x..y
即為數值範圍在 x
與 y
區間
until
類似 ..
操作符號,差別在於最後的數值會是目標值 -1
,例如 1 until 3
會印出「1 2」
rangeTo
與 ..
屬於相同效果
downTo
表示為反向區間,例如 x downTo y
即為 x
遞減到 y
step
為指定區間遞增或遞減值,例如 x .. y step 2
即為 x
每次遞增 2
到目標值 y
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| fun main() { for (i in 1..4) print(i)
for (i in 1.rangeTo(4)) println(i)
for (i in 1 until 4) println(i)
for (i in 4 downTo 1) print(i)
println((1..12 step 2).last)
for (i in 8 downTo 5 step 2) print(i)
for (i in 'a' .. 'd') println(i) }
|
在其他程式語言中,我們常會看見迴圈可以搭配 break
與 continue
方法, break
可讓當前迴圈直接整個結束,continue
則是可讓迴圈結束單次運行,而在 Kotlin 可以為迴圈指定名稱,當我們今天運用巢狀迴圈時,可指定要讓哪一個迴圈結束,如下範例:
迴圈在 item1
為 1 與 item2
為 0 時,結束外層單次中斷
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| fun main() { a@for(item1 in 0 until 3){ b@for(item2 in 0 until 3){ if(item1 == 1 && item2 == 0){ continue@a } println("$element1 => $element2") } } }
|
迴圈在 item1
為 1 與 item2
為 1 時,結束外層迴圈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| fun main() { a@for(item1 in 0 until 3){ b@for(item2 in 0 until 3){ println("$element => $element1") if(item1 == 1 && item2 == 1){ break@a } } } }
|