iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 4
0

此篇將介紹 Kotlin 在流程控制相關語法與特性,在 Kotlin 世界中,條件運算式、迴圈使用方式與其他程式語言相似,這邊快速帶大家了解在 Kotlin 中如何操作。

條件判斷

1. if..else 操作

在專案開發中,我們經常會使用到條件判斷來處理邏輯問題,我們可以直接利用下面範例來觀看 Kotlin 在 if..else 的操作,參考如下:

範例是當我們輸入分數(0-100)時,程式會依據所輸入的分數輸出對應的訊息

fun main() {
	print("請輸入分數:")
	// 宣告 Score 變數並將使用者輸入數值轉為 Int 
    val score: Int = readLine()!!.toInt()

	// 利用 if 判斷輸出對應結果
    if (score == 100) {        // 當分數為 100 時
        println("恭喜考滿分")
    } else if (score >= 60) {  // 當分數大於 60 時
        println("恭喜及格")
    } else if (score >= 0) {   // 當分數大於 0 且小於 60 時
        println("再接再勵")
    } else { 
        println("數值必須介於 0 - 100 之間")  // 當數值不是介於 0 - 100 時
    }
}

備註: !! 操作符號為非空斷言(Not-null assertion operator),表示我們認為輸入的數值不會是空值,若為空值則會立即出現錯誤狀況,而假如我們不使用 !! 操作符號時,Intellij 編輯器會告訴我們轉型會有錯誤,可參考下圖實際狀況:
https://ithelp.ithome.com.tw/upload/images/20200913/20121179wHHDQvaUeD.png

而與其他語言相比,Kotlin 比較特別的是條件判斷式可根據條件同時進行變數賦值,我們將上面範例改為以下程式:

此範例我們改變上面範例,使用判斷式賦值方法將分數所對應的回應字串回傳給 output 變數,再印出結果

fun main() {
    print("請輸入分數:")
    // 宣告 score 變數並將使用者輸入數值轉為 Int
    val score: Int = readLine()!!.toInt()
	// 宣告 output 變數儲存分數對應的回應字串
    val output: String =
        if (score == 100) // 當分數為 100 時
            "恭喜考滿分"
        else if (score >= 60) // 當分數大於 60 時
            "恭喜及格"
        else if (score >= 0) // 當分數大於 0 且小於 60 時
            "再接再勵"
				else // 當數值不是介於 0 - 100 時
						"成績輸入錯誤"
    println(output)
}

2. When 運算式

Kotlin 與其他程式語言比較不同的還有 when 運算式, 在 Kotlin 中,沒有提供其他語言常見的 switch 表達式,而是提供 when 表達式,when 是 Kotlin 的另一個控制流程語法,允許開發者編寫條件式,當滿足某個條件時執行對應程式碼,語法上非常簡潔,條件與執行程式用 箭頭符號語法進行配對,此方法適合三到四個流程情況使用,範例如下:

此範例先定義一個 score 變數,再利用 when 表達式進行分數判斷,再回傳對應的訊息,此部份記得此表達式與傳統 switch 不同,when 在條件結束時不需要加上 break

fun main() {
    print("請輸入分數:")
    // 宣告 score 變數並將使用者輸入數值轉為 Int
    val score: Int = readLine()!!.toInt()
    // 宣告 comment 變數並將分數對應的回應字串儲存
    val comment: String = when (score) {
        100 -> "恭喜滿分"
        in 60..99 -> "恭喜及格"
        in 0..60 -> "再接再勵"
        else -> "分數輸入錯誤"
    }
    println(comment)
}

when 也可以同時多條件判斷,我們試著將上面範例修改為以下:

fun main() {
    print("請輸入分數:")
    // 宣告 score 變數並將使用者輸入數值轉為 Int
    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,則有預設值進行替代或拋出錯誤提醒,原先情況我們可能會如下範例進行撰寫:

fun main() {
    val username: String? = "Devin"
    val usernameLength: Int =
        if (username == null) {
            0
        } else {
            username.length
        }
    println(usernameLength) // 輸出 username 字元長度 5
}

而 Kotlin 提供 elvis 語法,可以簡單處理這種情況:

fun main() {
    // 若為空,則回傳 0
    val username: String? = null
    val usernameLength: Int = username?.length ?: 0
    println(usernameLength) // 輸出 0 

    // 拋出錯誤
    val password: String? = null
    val passwordLength: Int = password?.length ?: throw IllegalArgumentException("資料為 null")
    println(passwordLength) // 輸出 Exception in thread "main" java.lang.IllegalArgumentException: 資料為 null
}

使用 ?: 即可檢查對應的值是否為 null,若為否,則回傳右邊的數值,此數值若開發者不想賦予任何值,也可以使用 return 回傳

val username: String? = "Devin"
val usernameLength: Int = username?.length ?: return
println(usernameLength) // 此行不會執行

迴圈使用

迴圈是程式依據設定的條件進行重複工作,當條件為真就持續進行,反之就結束,而 Kotlin 在迴圈方法上提供與Java 相同,都有 forwhiledo while 等方法,其中 Kotlin 迴圈操作的方式非常像 Python,如下範例所示 - 利用 for 迴圈將集合內所有元素逐步印出:

// 使用 for in 迴圈
val names = listOf("Anne", "Peter", "Jeff")
for (name in names) {
    println(name)
}

// 使用 while 迴圈
val number = 0
while (number < 10) {
	println(number)
	number++
}

// 使用 do...while 迴圈
val doorPassword = "20200913"
var keyInAmount= 0
do {
	println("請輸入密碼進門")
	val password = readLine()!! // 轉換 nullable to non-nullable
	keyInAmount++
} while (password != doorPassword && keyInAmount < 3)

Kotlin 也提供 Ranges 表達式可讓開發者快速建立兩個值的區間,一般通常會與inin! 一起使用,其餘操作如下說明與實作範例,建議閱讀朋友可以直接:

  1. .. 操作符號表示為數值區間,例如 x..y 即為數值範圍在 xy 區間
  2. until 類似 .. 操作符號,差別在於最後的數值會是目標值 -1,例如 1 until 3 會印出「1 2」
  3. rangeTo.. 屬於相同效果
  4. downTo 表示為反向區間,例如 x downTo y 即為 x 遞減到 y
  5. step 為指定區間遞增或遞減值,例如 x .. y step 2 即為 x 每次遞增 2 到目標值 y
fun main() {
	// 建立1-4區間數值
	for (i in 1..4) print(i) // 此段會印出「1 2 3 4」
	
	// rangeTo 與 .. 屬於相同效果
	for (i in 1.rangeTo(4)) println(i) //此段會印出「1 2 3 4」
	
	// until 與 .. 類似相同效果,差別在最終值會-1,
	for (i in 1 until 4) println(i) // 此段會印出「1 2 3」
	
	// downTo 為反向區間使用
	for (i in 4 downTo 1) print(i) // 此段會印出「4 3 2 1」
	
	// last方法會只輸出區間最後一個值,若要輸出第一個值,可以使用 first 方法
	println((1..12 step 2).last)  // 此段會印出「11」
	
	// 組合 downTo 與 step 方法
	for (i in 8 downTo 5 step 2) print(i)  // 此段會印出「8 6」
	
	// 區間也可以使用字母
	for (i in 'a' .. 'd') println(i) // 此段會印出「a b c d」
}

在其他程式語言中,我們常會看見迴圈可以搭配 breakcontinue 方法, break 可讓當前迴圈直接整個結束,continue 則是可讓迴圈結束單次運行,而在 Kotlin 可以為迴圈指定名稱,當我們今天運用巢狀迴圈時,可指定要讓哪一個迴圈結束,如下範例:

迴圈在 item1 為 1 與 item2 為 0 時,結束外層單次中斷

fun main() {
	// 命名外層迴圈為名稱「a」 
    a@for(item1 in 0 until 3){
		// 命名內層迴圈為名稱「b」
        b@for(item2 in 0 until 3){
			// 當符合條件時結束外層(a)迴圈跳過此次運行
            if(item1 == 1 && item2 == 0){
                continue@a
            }
            println("$element1 => $element2")
        }
    }
}

// 印出結果為
// 0 => 0
// 0 => 1
// 0 => 2
// 2 => 0
// 2 => 1
// 2 => 2

迴圈在 item1 為 1 與 item2 為 1 時,結束外層迴圈

fun main() {
    // 命名外層迴圈為名稱「a」 
    a@for(item1 in 0 until 3){
        // 命名內層迴圈為名稱「b」
        b@for(item2 in 0 until 3){
            println("$element => $element1")
            // 當符合條件時結束整個外層(a)迴圈
            if(item1 == 1 && item2 == 1){
                break@a
            }
        }
    }
}

// 印出結果為
// 0 => 0
// 0 => 1
// 0 => 2
// 1 => 0
// 1 => 1

上一篇
[Day 03] 遠征 Kotlin × 變數型別
下一篇
[Day 05] 遠征 Kotlin × 函數介紹
系列文
30天從零撰寫 Kotlin 語言並應用於 Spring Boot 開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言