【Kotlin】第2課-條件判斷

條件判斷是程式流程控制的一環,一般來說會有「if-else」和「switch」兩種。Kotlin 的條件判斷敘述也不例外,甚至能直接用來賦值給變數,比 Java 更有變化。本文就來認識它們。

一、if-else 敘述

實際上,Kotlin 的 if-else 敘述跟 Java 一模一樣,因此筆者在這邊就簡單提點一下,快速帶過。

val memberLevel = "Bronze"
val discountRate: Double

if (memberLevel.equals("Bronze"))
discountRate = 0.05
else if (memberLevel.equals("Sliver"))
discountRate = 0.1
else if (memberLevel.equals("Gold"))
discountRate = 0.15
else {
println("No discount.")
discountRate = 0.0
}

println(discountRate)

以上的範例是根據會員等級(memberLevel),來決定折扣率(discountRate)的值。如果條件成立後要執行的程式碼只有一行,也可以省略大括號。


二、用 if-else 敘述賦值

有時我們會需要像前一節那樣,根據條件來決定某個變數的值。而 Kotlin 的條件判斷敘述比較特別,它能夠像方法那樣回傳值給變數。因此第一節的程式可以改寫成如下。

val memberLevel = "Bronze"

val discountRate: Double =
if (memberLevel.equals("Bronze"))
0.05
else if (memberLevel.equals("Sliver"))
0.1
else if (memberLevel.equals("Gold"))
0.15
else {
println("No discount.")
0.0
}

println(discountRate)

在 if 各分支的內部敘述,可以撰寫其他程式碼,並將回傳值寫在最後一行。而且必須要有 else,以顧慮條件均不符合的情形,這種寫法取代了 Java 的三元運算子。但若不回傳值,而使用了「return」或拋出例外,則將從目前所在的方法返回或結束。

假設宣告該變數時未定義型態,且各個分支的回傳值型態不一致,則變數的型態會變成 AnyAny 就像 Java 的 Object,是最高級別的父類別。


三、when 敘述(一)

Kotlin 的 when 敘述類似 Java 的 switch 敘述。Java 的 switch只能判斷變數等於哪一個值,但 Kotlin 的 when 卻可以有其他用法。首先我們簡單地將第一節介紹的 if 敘述以 when 改寫,以作為示範。

val memberLevel = "Gold"

val discountRate: Double

when (memberLevel) {
"Bronze" -> discountRate = 0.05
"Sliver" -> discountRate = 0.1
"Gold" -> discountRate = 0.15
else -> {
println("No discount.")
discountRate = 0.0
}
}

println(discountRate)

 使用 when 傳入一個要判斷的參數。接著在內部的分支撰寫各條件對應要執行的程式,兩者用「->」語法隔開。而當有多個條件成立,都要執行相同程式時,則使用「,」符號隔開。

這個範例是仿照 Java 的「switch-case」。第一個差別是不必使用 break 來跳出敘述。第二個差別是 when 敘述規定要考慮條件均不成立的情況,因此需要用「else」來定義預設的處理方式。

四、when 敘述(二)

when 的第二種用法是作為 if-else 的替代方案。這兩種寫法的效果一模一樣,可以定義各種條件,而非只是判斷一個值而已。

觀察一下第三節範例的判斷方式,若是遇到如「gold」的字串,則程式會走向 else,這情形不是很合理。這邊利用 when 的第二種用法來改寫。

val memberLevel = "gold"

val discountRate: Double

when {
memberLevel.equals("Bronze", true) -> discountRate = 0.05
memberLevel.equals("Sliver", true) -> discountRate = 0.1
memberLevel.equals("Gold", true) -> discountRate = 0.15
else -> {
println("No discount.")
discountRate = 0.0
}
}

println(discountRate)

此寫法不需傳入參數給 when。且分支的左邊是會回傳 Boolean 的敘述,例如方法或判斷式。此處使用判斷字串相等的方法,並忽略大小寫。


五、用when敘述賦值

when 敘述跟 if 敘述一樣可以給變數賦予值。以上 when 的兩種寫法都可以達成,概念也和 if 相同,此處就不贅述。

val memberLevel = "GOLD"

val discountRate =
when (memberLevel) {
"Bronze", "BRONZE" -> 0.05
"Sliver", "SLIVER" -> 0.1
"Gold", "GOLD" -> 0.15
else -> {
println("No discount.")
0.0
}
}

println(discountRate)


六、遇到 null 就賦予另一個值

變數可以透過方法或其他敘述來賦予值,但若希望當原本要賦予的值很不巧是 null 時,能有個預設值來替代,我們可能會像這樣寫。

val title: String? = "Human Resource"
val titleLength: Int =
if (title == null) {
0
} else {
title.length
}

Kotlin 提供一種叫做「evlis」的語法,可以簡單地處理這種情形。

val title: String? = "Human Resource"
val titleLength: Int = title?.length ?: 0

使用「?:」語法,可以檢查左邊的值,如果不是 null,就用它來賦予變數值,否則就採用右邊的值。右邊除了能定義備用的值,也能使用「return」或拋出例外的敘述。若左邊的值是 null,便會直接從目前所在的方法返回或拋出想要的例外,而不執行後面的程式,範例如下。

var title: String? = "Human Resource"
var titleLength: Int = title?.length ?: return
print(titleLength) // 印出14

title = null
titleLength = title?.length ?: return // 程式到此結束並返回
print(titleLength) // 不會執行

變數 title 被設為 null 後,使用其方法的回傳值依然會是 null。接著遇上「?:」的語法,便會執行右邊的敘述,從方法返回。

上一篇:【Kotlin】第1課-宣告變數與方法

下一篇:【Kotlin】第3課-迴圈

留言