在 Kotlin 中編寫條件式

1. 事前準備

條件式是程式設計最重要的基礎之一,也是程式語言中負責處理決策的指令。條件式可讓程式碼保有動態特質,也就是說在不同的條件下呈現不同行為。

本程式碼研究室會指導您如何使用 if/elsewhen 陳述式及運算式,進而在 Kotlin 中編寫條件式。

必要條件

  • Kotlin 程式設計的基本知識,包括變數與 println()main() 函式。

課程內容

  • 如何編寫布林運算式。
  • 如何編寫 if/else 陳述式。
  • 如何編寫 when 陳述式。
  • 如何編寫 if/else 運算式。
  • 如何編寫 when 運算式。
  • 如何在 when 條件式中使用逗號來定義多個分支的常見行為。
  • 如何在 when 條件式中使用 in 範圍定義一連串分支的常見行為。
  • 如何使用 is 關鍵字編寫 when 條件陳述式。

軟硬體需求

  • 可使用 Kotlin Playground 的網路瀏覽器。

2. 使用 if/else 陳述式表示條件

在現實生活中,我們往往會根據實際遇到的情況而採取不同的行動。舉例來說,天氣寒冷要穿外套,天氣炎熱就不必穿。

這張流程圖說明天氣寒冷時的決策模式。標有「是」的箭頭指向「穿外套」訊息,標有「否」的箭頭指向「不穿外套」訊息。

決策制定也是程式設計中的基本概念。透過編寫指令,您可以說明程式在特定情況下的行為方式,進而在該情境發生時採取相應行動或回應。在 Kotlin 中,如果您希望程式根據條件執行不同動作,可以使用 if/else 陳述式。在下一節中,您將編寫 if 陳述式。

透過布林運算式編寫 if 條件式

設想一下,您建構了一個程式,告訴駕駛人看到交通號誌時應採取什麼行動。首先來看看第一個條件:紅燈。遇到紅燈時,您會怎麼做?當然是停車!

這張流程圖說明遇到紅燈時的決策模式。標有「是」的箭頭指向「停車!」訊息。

在 Kotlin 中,您可以使用 if 陳述式來表示這個條件。我們來看看 if 陳述式的結構剖析:

這張圖說明 if 陳述式的結構。首先,if 關鍵字後面有一組括號,當中包含一個條件。接著是一組大括號,主體位於其中。條件區塊則以醒目的顏色標示。

如要使用 if 陳述式,您必須先使用 if 關鍵字,後面加上您要評估的條件。該條件必須透過布林運算式表示。「運算式」結合了值、變數和會傳回值的運算子。而布林運算式會傳回布林值。

我們先前已介紹「指派運算子」的相關知識,例如:

val number = 1

= 指派運算子為 number 變數指派了 1 值。

相反地,布林值運算式的建構基礎是「比較運算子」,可用來比較等式兩邊的值或變數。一起來看看比較運算子的例子。

1 == 1

== 比較運算子會相互比較這些值。你認為這個運算式會傳回哪個布林值?

試著找出這個運算式的布林值:

  1. 使用 Kotlin Playground 執行您的程式碼。
  2. 在函式主體中新增 println() 函式,然後將 1 == 1 運算式做為引數傳遞給該函式:
fun main() {
    println(1 == 1)
}
  1. 執行程式,然後查看輸出內容:
true

第一個 1 值等於第二個 1 值,因此布林運算式會傳回一個 true 值,也就是布林值。

試試看

除了 == 比較運算子之外,您還可以透過其他「比較運算子」建立布林運算式:

  • 小於:<
  • 大於:>
  • 小於或等於:<=
  • 大於或等於:>=
  • 不等於:!=

現在請透過簡單的運算式練習使用比較運算子:

  1. 在引數中,將 == 比較運算子替換為 < 比較運算子:
fun main() {
    println(1 < 1)
}
  1. 執行程式,然後查看輸出內容:

由於第一個 1 值「並未」小於第二個 1 值,因此輸出內容會傳回 false 值。

false
  1. 使用其他比較運算子和數字重複執行前兩個步驟。

編寫簡單的 if 陳述式

您已經看過幾個說明如何編寫布林運算式的範例,現在可以編寫您的第一個 if 陳述式。if 陳述式的語法如下:

這張圖說明 if 陳述式的結構。首先,if 關鍵字後面有一組括號,當中包含一個條件。接著是一組大括號,主體位於其中。主體區塊則以醒目的顏色標示。

if 陳述式以關鍵字 if 開頭,後面接著條件 (括號中的布林運算式) 和一組大括號。主體是一連串的陳述式或運算式,位於條件後方的大括號內。這些陳述式或運算式只會在條件符合的情況下執行。換句話說,只有在 if 分支中的布林運算式傳回 true 值時,大括號中的陳述式才會執行。

現在請針對紅燈條件編寫 if 陳述式:

  1. main() 函式中建立 trafficLightColor 變數,並為其指派 "Red" 值:
fun main() {
    val trafficLightColor = "Red"
}
  1. 針對紅燈條件新增 if 陳述式,然後將 trafficLightColor == "Red" 運算式傳遞給該陳述式:
fun main() {
    val trafficLightColor = "Red"

    if (trafficLightColor == "Red") {

    }
}
  1. if 陳述式的主體中新增 println() 函式,然後將 "Stop" 引數傳遞給該函式:
fun main() {
    val trafficLightColor = "Red"

    if (trafficLightColor == "Red") {
        println("Stop")
    }
}
  1. 執行程式,然後查看輸出內容:
Stop

trafficLightColor == "Red" 運算式會傳回 true 值,因此系統會執行 println("Stop") 陳述式,輸出 Stop 訊息。

這張圖將 trafficLightColor == "Red" 的 if 陳述式醒目標示為布林運算式和條件。下一行則註明 println("Stop") 主體只會在布林運算式為 true 時執行。

新增 else 分支

現在,您可以延長程式內容,讓駕駛人在非紅燈的情況下「行駛」

這張流程圖說明遇到紅燈時的決策模式。標有「是」的箭頭指向「停車!」訊息。標有「否」的箭頭指向「行駛」訊息。

您必須新增 else 分支才能建立 if/else 陳述式。「分支」是不完整的程式碼,您可以將這些程式碼彙整組成陳述式或運算式。else 分支必須接在 if 分支之後。

這張圖說明 if/else 陳述式的結構。首先,if 關鍵字後面有一組括號,當中包含一個條件。接著是一組大括號,主體 1 位於其中。再後面是 else 關鍵字和一組括號。最後則是一組大括號,主體 2 區塊位於其中。

if 陳述式的右大括號後面,我們會先新增 else 關鍵字,後方接著一組大括號。在 else 陳述式的大括號內,您可以新增第二個主體,這個主體只會在 if 分支的條件為 false 時執行。

在程式中新增 else 分支:

  1. if 陳述式的右大括號後面新增 else 關鍵字,後方接著另一組大括號。
fun main() {
    val trafficLightColor = "Red"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else {

    }
}
  1. else 關鍵字的大括號內加入 println() 函式,然後將 "Go" 引數傳遞給該函式:
fun main() {
    val trafficLightColor = "Red"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else {
        println("Go")
    }
}
  1. 執行這個程式,然後查看輸出內容:
Stop

該程式仍會以您新增 else 分支前的行為模式運作,但不會輸出 Go 訊息。

  1. trafficLightColor 變數重新指派為 Green 值,因為您想讓駕駛人在綠燈時「行駛」
fun main() {
    val trafficLightColor = "Green"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else {
        println("Go")
    }
}
  1. 執行這個程式,然後查看輸出內容:
Go

如您所見,現在程式會輸出 Go 訊息,而不是 Stop 訊息。

這張圖醒目標示 if/else 陳述式,其中將 trafficLightColor == "Red" 條件註明為布林運算式。同時,我們也標註 println("Stop") 主體只會在布林運算式為 true 時執行。而在 else 子句中,則註明 println("Go") 陳述式只會在布林運算式為 false 時執行。

您已將 trafficLightColor 變數重新指派為 "Green" 值,因此在 if 分支中評估的 trafficLightColor == "Red" 運算式會傳回 false 值,因為 "Green" 值不等於"Red" 值。

因此,程式會略過 if 分支中的所有陳述式,改為執行 else 分支內的所有陳述式。也就是說,系統會執行 println("Go") 函式,但不會執行 println("Stop") 函式。

新增 else if 分支

一般來說,黃燈也是交通號誌的一種,用於告訴駕駛人應緩慢行駛。我們可以延長程式的決策流程來反映這一點。

這張流程圖說明遇到紅燈時的決策模式。標有「是」的箭頭指向「停車!」訊息。標有「否」的箭頭指向另一個情況,說明遇到黃燈時的決策模式。從該決策點中,標有「是」的箭頭指向「慢行」訊息,標有「否」的箭頭則指向「行駛」訊息。

您已學會如何透過含有單一 if 和單一 else 分支的 if/else 陳述式,編寫適用於單一決策點的條件式。現在要如何處理含有多個決策點、結構更為複雜的分支架構呢?面對多個決策點時,您必須建立含有多層條件的條件式,具體做法是將 else if 分支新增至 if/else 陳述式。

if 分支的右大括號後面,您必須新增 else if 關鍵字。在 else if 關鍵字的括號內,您必須新增布林運算式做為 else if 分支的條件,並在後方加上前後標有大括號的主體。只有在條件 1 不符但條件 2 符合時,主體才會執行。

這張圖說明 if/else 陳述式的結構。首先,if 關鍵字後面有一組括號,當中包含條件 1 區塊。接著是一組大括號,主體 1 位於其中。再來是 else if 關鍵字,後方的括號中含有條件 2 區塊。然後是一組大括號,其中有主體 2 區塊。最後是 else 關鍵字,後方有一組大括號,其中包含主體 3 區塊。

else if 分支一律位於 if 分支後、else 分支前。您可以在陳述式中使用多個 else if 分支:

這張圖顯示 if/else 條件,在 if 和 else 分支之間,又有多個 else if 分支。這些 else if 分支旁邊標有註解文字,指出此處有多個 else if 分支。

if 陳述式也可包含不含任何 else 分支的 if 分支和 else if 分支:

這張圖說明 if/else 陳述式的結構。首先,if 關鍵字後面有一組括號,當中包含條件 1 區塊。接著是一組大括號,主體 1 位於其中。再來是 else if 關鍵字,後方的括號中含有條件 2 區塊。然後是一組大括號,其中有主體 2 區塊。

在程式中新增 else if 分支:

  1. if 陳述式的右大括號後面加上 else if (trafficLightColor == "Yellow") 運算式,後方接著大括號:
fun main() {
    val trafficLightColor = "Green"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {

    } else {
        println("Go")
    }
}
  1. else if 分支的大括號內加上 println() 陳述式,然後將 "Slow" 字串引數傳遞給該陳述式:
fun main() {
    val trafficLightColor = "Green"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else {
        println("Go")
    }
}
  1. trafficLightColor 變數重新指派為 "Yellow" 字串值:
fun main() {
    val trafficLightColor = "Yellow"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else {
        println("Go")
    }
}
  1. 執行這個程式,然後查看輸出內容:
Slow

現在,程式會輸出 Slow 訊息,而不是 StopGo 訊息。

這張圖醒目標示 if/else 陳述式,其中將 if 子句的 trafficLightColor == "Red" 註明為布林運算式 1,trafficLightColor == "Yellow" 則註明為布林運算式 2。同時,我們也標註 println("stop") 主體只會在布林運算式 1 為 true 時執行;而 println("slow") 主體只會在布林運算式 1 為 false、但布林運算式 2 為 true 時執行。至於 println("go") 主體,則註明只會在布林陳述式 1 和 2 皆為 false 時執行。

以下說明為何只輸出 Slow 訊息,而不是其他內容:

  • trafficLightColor 變數獲派 "Yellow" 值。
  • "Yellow" 值不等於 "Red" 值,因此 if 分支的布林值運算式 (圖中標示為 1) 會傳回 false 值。程式會略過 if 分支內的所有陳述式,且不會輸出 Stop 訊息。
  • 由於 if 分支會產生 false 值,因此程式會繼續評估 else if 分支內的布林值運算式。
  • "Yellow" 值等於 "Yellow" 值,因此 else if 分支的布林值運算式 (圖中標示為 2) 會傳回 true 值。程式會執行 else if 分支中的所有陳述式,並輸出 Slow 訊息。
  • 由於 else if 分支的布林值 expression 會傳回 true 值,因此程式會略過分支的其餘部分。因此,else 分支中的所有陳述式都不會執行,程式也不會輸出 Go 訊息。

試試看

您是否發現目前的程式含有錯誤?

在單元 1 中,我們已介紹一種名為「編譯錯誤」的問題,這是因為程式碼中的語法錯誤導致 Kotlin 無法編譯程式碼,因而無法執行程式。這裡我們遇到了另一種錯誤,也就是「邏輯錯誤」,這是指程式能夠執行,但不會產生預期的輸出內容。

假設您只想讓駕駛人在綠燈時行駛,那如果交通號誌壞了,該怎麼辦?您希望駕駛人行駛,還是收到錯誤的警告呢?

可惜的是在目前的程式中,只要交通號誌「不是」紅燈或黃燈,系統就還是會建議駕駛人往前「行駛」

我們來修正這個問題:

  1. trafficLightColor 變數重新指派為 "Black" 值,表示交通號誌無法運作:
fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else {
        println("Go")
    }
}
  1. 執行這個程式,然後查看輸出內容:
Go

請注意,即使 trafficLightColor 變數並未獲派 "Green" 值,程式仍會輸出 Go 訊息。您能修正這個程式,反映正確的行為嗎?

這張流程圖說明遇到紅燈時的決策模式。標有「是」的箭頭指向「停車!」訊息。標有「否」的箭頭指向另一個情況,說明遇到黃燈時的決策模式。從該決策中,標有「是」的箭頭指向「慢行」訊息,標有「否」的箭頭則指向另一個情況,說明遇到綠燈時的決策模式。從該決策中,標有「是」的箭頭指向「行駛」訊息,標有「否」的箭頭則指向「無效燈色」訊息。

您必須修改程式,使其輸出下列內容:

  • Go 訊息 (僅限 trafficLightColor 變數獲派 "Green" 值時)。
  • Invalid traffic-light color 訊息 (當 trafficLightColor 變數未獲派 "Red""Yellow""Green" 值時)。

修正 else 分支

else 分支是通用分支,因此一律位於 if/else 陳述式的結尾。如果先前分支中的所有其他條件都不符,這個分支就會自動執行。因此,如果您希望只在動作滿足特定條件時才執行,就不適合使用 else 分支。以交通號誌的例子來說,您可以使用 else if 分支來指定綠燈的條件。

請使用 else if 分支評估綠燈的條件:

  1. 在目前的 else if 分支後,加上另一個 else if (trafficLightColor == "Green") 分支:
fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    }
}
  1. 執行這個程式,然後查看輸出內容。

輸出內容為空白,原因是您沒有會在不符上述條件時執行的 else 分支。

  1. 在最後一個 else if 分支後新增 else 分支,並在其中加入 println("Invalid traffic-light color") 陳述式:
fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    } else {
        println("Invalid traffic-light color")
    }

}
  1. 執行這個程式,然後查看輸出內容:
Invalid traffic-light color
  1. trafficLightColor 變數指派 "Red""Yellow""Green" 以外的其他值,然後重新執行程式。

程式會輸出什麼內容?

建議您以明確的 else if 分支做為輸入內容在綠燈時的驗證機制,並使用 else 分支來擷取其他無效的輸入內容。這樣一來,系統就只會在綠燈時才指示駕駛人「行駛」。至於其他情況,則有明確訊息指出交通號誌無法按預期運作。

3. 針對多個分支使用 when 陳述式

trafficLightColor 程式若含有多項條件 (也就是所謂的分支),看起來就會更加複雜。您可能會想知道是否能簡化含有更多分支的程式。

在 Kotlin 中,如要處理多個分支,您可以改用 when 陳述式取代 if/else 陳述式,這是因為前者的可讀性較高;所謂可讀性,是指人類讀者 (通常是開發人員) 讀取程式碼的難易程度,編寫程式碼時,請務必考量可讀性問題,因為在程式碼的生命週期內,可能會有其他開發人員需要檢查及修改程式碼,維持高可讀性能讓您確保開發人員正確理解程式碼,避免無意間帶入錯誤。

如果要考慮的分支超過兩個,建議使用 when 陳述式。

這張圖顯示 when 陳述式的剖析結構。首先,when 關鍵字後面有一組括號,當中包含一個參數區塊。接著是一組大括號,內含三行案例。而在每行中都有一個條件區塊,後面接著箭頭符號和主體區塊,旁邊標註系統會逐行評估每個案例。

when 陳述式會透過參數接受單一值。系統隨後便會按照各項條件依序評估這個值。如果第一個條件符合,相應的主體就會執行。每個條件和主體會以箭頭 (->) 分隔。類似於 if/else 陳述式,每組條件和主體都稱為 when 陳述式中的分支。同樣與 if/else 陳述式類似的是,您可以在 when 陳述式中加入 else 分支做為最終條件,功能相當於通用分支。

利用 when 陳述式重新編寫 if/else 陳述式

在交通號誌程式中,已經有許多分支:

  • 紅燈
  • 黃燈
  • 綠燈
  • 其他燈色

將程式轉換成使用 when 陳述式:

  1. main() 函式中,移除 if/else 陳述式:
fun main() {
    val trafficLightColor = "Black"

}
  1. 新增 when 陳述式,然後將 trafficLightColor 變數做為引數傳遞給該陳述式:
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
    }
}
  1. when 陳述式的主體中新增 "Red" 條件,後面接著箭頭和 println("Stop") 主體:
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
        "Red" -> println("Stop")
    }
}
  1. 在下一行中新增 "Yellow" 條件,後面加上箭頭和 println("Slow") 主體:
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
    }
}
  1. 在下一行中新增 "Green" 條件,後面加上箭頭和 println("Go") 主體:
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
    }
}
  1. 在下一行中加入 else 關鍵字,後面接著箭頭和 println("Invalid traffic-light color") 主體:
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}
  1. trafficLightColor 變數重新指派為 "Yellow" 值:
fun main() {
    val trafficLightColor = "Yellow"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}

執行這個程式時,您認為輸出內容會是什麼?

  1. 執行程式,然後查看輸出內容:
Slow

這張圖針對 when 陳述式提供註解說明。"Red" -> println("Stop") 行加註為案例 1。"Yellow" -> println("Slow") 行加註為案例 2。"Green" -> println("Go") 行加註為案例 3。else -> println("Invalid traffic-light color") 行加註為案例 4。

輸出內容為 Slow 訊息,原因如下:

  • trafficLightColor 變數獲派 "Yellow" 值。
  • 程式逐一評估各個條件。
  • "Yellow" 值不等於 "Red" 值,因此程式略過第一個主體。
  • "Yellow" 值等於 "Yellow" 值,因此程式會執行第二個主體,輸出 Slow 訊息。
  • 由於已執行主體,因此程式會忽略第三和第四個分支,結束 when 陳述式。

when 陳述式中編寫更複雜的條件

到目前為止,我們已說明如何為單一的相等條件編寫 when 條件,例如為 trafficLightColor 變數指派 "Yellow" 值。接下來要介紹如何使用逗號 (,)、in 關鍵字和 is 關鍵字建立更複雜的 when 條件。

建立程式,用於判斷 1 到 10 之間的數字是否為質數:

  1. 在另一個視窗中開啟 Kotlin playground

我們稍後會再回來說明交通號誌程式。

  1. 定義 x 變數,並為其指派 3 值:
fun main() {
    val x = 3
}
  1. 新增 when 陳述式,其中包含 2357 條件的多個分支,每個分支後面接有 println("x is prime number between 1 and 10.") 主體:
fun main() {
    val x = 3

    when (x) {
        2 -> println("x is a prime number between 1 and 10.")
        3 -> println("x is a prime number between 1 and 10.")
        5 -> println("x is a prime number between 1 and 10.")
        7 -> println("x is a prime number between 1 and 10.")
    }
}
  1. 新增具有 println("x is not prime number between 1 and 10.") 主體的 else 分支:
fun main() {
    val x = 3

    when (x) {
        2 -> println("x is a prime number between 1 and 10.")
        3 -> println("x is a prime number between 1 and 10.")
        5 -> println("x is a prime number between 1 and 10.")
        7 -> println("x is a prime number between 1 and 10.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. 執行程式,並確認輸出內容符合預期:
x is a prime number between 1 and 10.

針對多個條件使用逗號 (,)

質數程式中含有大量重複的 println() 陳述式。當您編寫 when 陳述式時,可以使用逗號 (,) 來標示對應同一主體的多個條件。

這張圖顯示 when 陳述式的剖析結構。首先,when 關鍵字後面有一組括號,當中包含一個參數區塊。接著是一組大括號,內含兩行案例。第一行是條件 1 區塊,後面接著逗號,然後是條件 2 區塊、箭頭符號和主體區塊。第二行則有一個條件區塊,後面接著箭頭符號和主體區塊。

在上圖中,如果符合第一或第二個條件,相應的主體就會執行。

現在我們利用這個概念重新編寫質數程式:

  1. 2 條件的分支中,新增 357,並以半形逗號 (,) 分隔:
fun main() {
    val x = 3

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        3 -> println("x is a prime number between 1 and 10.")
        5 -> println("x is a prime number between 1 and 10.")
        7 -> println("x is a prime number between 1 and 10.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. 移除 357 條件的個別分支:
fun main() {
    val x = 3

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. 執行程式,並確認輸出內容符合預期:
x is a prime number between 1 and 10.

針對一連串的條件使用 in 關鍵字

除了用逗號 (,) 來標示多個條件以外,您也可以在 when 分支中使用 in 關鍵字和一連串的值。

這張圖顯示 when 陳述式的剖析結構。首先,when 關鍵字後面有一組括號,當中包含一個參數區塊。接著是一組大括號,內含兩行案例。而在第一行中的是 in 關鍵字,後面接著範圍起始區塊、兩個黑點、範圍結束區塊、箭頭符號和主體區塊。第二行則有一個條件區塊,後面接著箭頭符號和主體區塊。

如要使用一連串的值,請先新增一個數字,用來表示範圍起點,接著加上兩個英文句點 (不含空格),然後以另一個數字表示該範圍的結尾。

當參數值等於範圍起點與範圍結尾之間的任何值時,第一個主體便會執行。

現在思考在質數程式中,如果數字介於 1 到 10 之間但不是質數,是否可以輸出訊息?

請使用 in 關鍵字新增其他分支:

  1. when 陳述式的第一個分支之後新增第二個分支,其中含有 in 關鍵字,後面接著 1..10 範圍和 println("x is a number between 1 and 10, but not a prime number.") 主體:
fun main() {
    val x = 3

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. x 變數變更為 4 值:
fun main() {
    val x = 4

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. 執行程式,然後確認輸出內容:
x is a number between 1 and 10, but not a prime number.

程式會輸出第二個分支的訊息,但不會輸出第一或第三個分支的訊息。

這張圖針對 when 陳述式提供註解說明。2,3,5,7 -> println("x is a prime number between 1 and 10.") 行加註為案例 1。in 1..10 -> println("x is a number between 1 and 10, but not a prime number.") 行加註為案例 2。else -> println("x isn't a prime number between 1 and 10.") 行加註為案例 3。

這個程式的運作方式如下:

  • x 變數獲派 4 值。
  • 程式繼續評估第一個分支的條件。4 值不是 2357 值,因此程式會略過第一個分支的主體,繼續執行第二個分支。
  • 4 值介於 110 之間,因此會輸出 x is a number between 1 and 10, but not a prime number. 主體的訊息。
  • 由於已執行主體,因此程式會繼續、結束 when 陳述式並忽略 else 分支。

使用 is 關鍵字檢查資料類型

您可以使用 is 關鍵字做為條件,藉此確認所評估值的資料類型。

這張圖顯示 when 陳述式的剖析結構。首先,when 關鍵字後面有一組括號,當中包含一個參數區塊。接著是一組大括號,內含兩行案例。而在第一行中有關鍵字,後面接著類型區塊、箭頭符號和主體區塊。第二行則含有一個條件區塊,後面接著箭頭符號和主體區塊。

在上圖中,如果引數的值是上述的資料類型,系統會執行第一個主體。

現在思考在質數程式中,如果輸入的整數不在 1 到 10 的範圍之內,是否可以輸出訊息?

請使用 is 關鍵字新增其他分支:

  1. x 修改為 Any 類型。這表示 x 的值不是 Int 類型。
fun main() {
    val x: Any = 4

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. when 陳述式的第二個分支之後,新增 is 關鍵字以及包含 println("x is an integer number, but not between 1 and 10.") 內文的 Int 資料類型:
fun main() {
    val x: Any = 4

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        is Int -> println("x is an integer number, but not between 1 and 10.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. else 分支中,將主體變更為 println("x isn't an integer number.") 主體:
fun main() {
    val x: Any = 4

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        is Int -> println("x is an integer number, but not between 1 and 10.")
        else -> println("x isn't an integer number.")
    }
}
  1. x 變數變更為 20 值:
fun main() {
    val x: Any = 20

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        is Int -> println("x is an integer number, but not between 1 and 10.")
        else -> println("x isn't an integer number.")
    }
}
  1. 執行程式,然後確認輸出內容:
x is an integer number, but not between 1 and 10.

程式會輸出第三個分支的訊息,但不會輸出第一、第二或第四個分支的訊息。

這張圖針對 when 陳述式提供註解說明。2,3,5,7 -> println("x is a prime number between 1 and 10.") 行加註為案例 1。in 1..10 -> println("x is a number between 1 and 10, but not a prime number.") 行加註為案例 2。is Int -> println("x is an integer number, but not between 1 and 10.") 行加註為案例 3。else -> println("x isn't an integer number.") 行加註為案例 4。

程式的運作方式如下:

  • x 變數獲派 20 值。
  • 程式繼續評估第一個分支的條件。20 值不是 2357 值,因此程式會略過第一個分支的主體,繼續執行第二個分支。
  • 20 值不在 110 的範圍內,因此程式會略過第二個分支的主體,繼續執行第三個分支。
  • 20 值屬於 Int 類型,因此系統會輸出 x is an integer number, but not between 1 and 10 主體。
  • 由於已執行主體,因此程式會繼續、結束 when 陳述式並忽略 else 分支。

試試看

現在來練習一下我們在交通號誌程式中學到的內容。

想像一下,在某些國家/地區有一種琥珀色的交通號誌燈,這種燈號可用來警告駕駛人,與其他國家/地區的黃燈相同。您可以修改程式,讓程式涵蓋這個額外條件,同時保有原有的條件嗎?

新增具有相同主體的額外條件

為交通號誌程式新增額外條件:

  1. 如果還沒關閉的話,請返回內含交通號誌程式的 Kotlin Playground 執行個體。
  2. 如果已經關閉的話,請開啟新的 Kotlin Playground 執行個體,並輸入以下程式碼:
fun main() {
    val trafficLightColor = "Yellow"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}
  1. when 陳述式的第二個分支中找到 "Yellow" 條件,然後在後方加上半形逗號和 "Amber" 條件:
fun main() {
    val trafficLightColor = "Yellow"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow", "Amber" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}
  1. trafficLightColor 變數變更為 "Amber" 值:
fun main() {
    val trafficLightColor = "Amber"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow", "Amber" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}
  1. 執行這個程式,然後確認輸出內容:
Slow

4. 將 if/else 和 when 用做運算式

我們已說明如何將 if/elsewhen 用做陳述式。當您將條件式用做陳述式時,可以讓各個分支根據條件在主體中執行不同的操作。

條件式也可以用做運算式,藉此為各個條件分支傳回不同的值。如果每個分支的主體看起來很相似,您便可以使用條件運算式。比起條件陳述式,這個做法可讓程式碼變得更容易閱讀。

這張圖說明 if/else 運算式的結構。首先,val 關鍵字後面有一個名稱區塊,後方接有等號、if 關鍵字、括號 (內含一個條件)、一組大括號 (內含主體 1 區塊)、else 關鍵字,然後又是一組大括號,而主體區塊位於其中。

條件式做為運算式時的語法與陳述式類似,但每個分支的最後一行主體必須傳回值或運算式,並將條件式指派給變數。

如果主體只包含傳回的值或運算式,您可以移除大括號,讓程式碼更加簡潔。

這張圖說明 if/else 運算式的結構。首先,val 關鍵字後面有一個名稱區塊,後方接有等號、if 關鍵字、括號 (內含一個條件)、運算式 1 區塊、else 關鍵字,然後是運算式 2 區塊。

下一節將透過交通號誌程式說明 if/else 運算式。

if 陳述式轉換為運算式

這個 if/else 陳述式中有許多重複的 println() 陳述式:

fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    } else {
        println("Invalid traffic-light color")
    }

}

將這個 if/else 陳述式轉換為 if/else 運算式,並移除上述重複內容:

  1. 在 Kotlin playground 中輸入先前的交通號誌程式。
  2. 定義 message 變數,並為其指派 if/else 陳述式:
fun main() {
    val trafficLightColor = "Black"

    val message = if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    } else {
        println("Invalid traffic-light color")
    }

}
  1. 移除所有 println() 陳述式及相應的大括號,但保留其中的值:
fun main() {
    val trafficLightColor = "Black"

    val message =
      if (trafficLightColor == "Red") "Stop"
      else if (trafficLightColor == "Yellow") "Slow"
      else if (trafficLightColor == "Green") "Go"
      else "Invalid traffic-light color"
}
  1. 在程式結尾新增 println() 陳述式,然後將 message 變數做為引數傳遞給該陳述式:
fun main() {
    val trafficLightColor = "Black"

    val message =
      if (trafficLightColor == "Red") "Stop"
      else if (trafficLightColor == "Yellow") "Slow"
      else if (trafficLightColor == "Green") "Go"
      else "Invalid traffic-light color"

    println(message)
}
  1. 執行這個程式,然後查看輸出內容:
Invalid traffic-light color

試試看

將交通號誌程式轉換為使用 when 運算式,而不是 when 陳述式:

  1. 在 Kotlin Playground 中,輸入以下程式碼:
fun main() {
    val trafficLightColor = "Amber"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow", "Amber" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}

您是否能將 when 陳述式轉換為運算式,避免 println() 陳述式重複?

  1. 建立 message 變數並將其指派給 when 運算式:
fun main() {
    val trafficLightColor = "Amber"

    val message = when(trafficLightColor) {
        "Red" -> "Stop"
        "Yellow", "Amber" -> "Proceed with caution."
        "Green" -> "Go"
        else -> "Invalid traffic-light color"
    }
}
  1. println() 陳述式新增為程式的最後一行,然後將 message 變數做為引數傳遞給該陳述式:
fun main() {
    val trafficLightColor = "Amber"

    val message = when(trafficLightColor) {
        "Red" -> "Stop"
        "Yellow", "Amber" -> "Proceed with caution."
        "Green" -> "Go"
        else -> "Invalid traffic-light color"
    }
    println(message)
}

5. 結語

恭喜!您已經認識條件式,對如何在 Kotlin 中編寫條件式也有所掌握。

摘要

  • 在 Kotlin 中,您可以使用 if/elsewhen 條件式來建立分支。
  • if/else 條件式中的 if 分支主體只有在 if 分支條件內的布林運算式傳回 true 值時才會執行。
  • if/else 條件式中的後續 else if 分支只有在先前的 ifelse if 分支傳回 false 值時才會執行。
  • if/else 條件式中的最後一個 else 分支只有在所有先前的 ifelse if 分支都傳回 false 值時才會執行。
  • 當有超過兩個分支時,建議使用 when 條件式來取代 if/else 條件式。
  • 您可以利用逗號 (,)、in 範圍和 is 關鍵字,在 when 條件式中編寫更複雜的條件。
  • 除了陳述式外,if/elsewhen 條件式也可用做運算式。

瞭解詳情