「Kotlin 2.2.0 新語法快遞」:在 when 內加入防衛條件(Guard Conditions)
Kotlin 2.2.0 即將到來,目前在 2.2.0 的候選版本(2.2.0-RC2)中,包含了幾項新的語法改善,就讓我帶給各位。 首先,第一個新到來的功能為在 when 條件運算式中加入防衛條件
在 when 條件運算式中加入防衛條件(Guard Conditions)
在 2.1.0 中,when 條件運算式中加入防衛條件
已經進入預覽(Preview)階段,而到了 2.2.0,已經進入穩定(Stable)。那麼這項語法的改進,有著什麼優點呢?
我們知道,when
是一個條件運算式,而我們可以在這裡面給出不同的判斷,進而執行不同的分支。
在 when
裡面加上判斷條件,並在 when 的範圍內(括號內)處理各種條件,如下 calculate()
函式所示範:
fun calculate(number1: Int, number2: Int) {
when (val result = number1 - number2) {
0 -> println("number1 equals number2")
in 1..10 -> println("result is positive and between 1 and 10: $result")
in -10..-1 -> println("result is negative and between -10 and -1: $result")
else -> println("result is $result")
}
}
若我們打算將運算子右邊的結果再加上一些判斷,譬如判斷是否為偶數。我們可以直接在運算子 ->
後方串上 if 判斷式,同時需要一併加上 else,如下:
fun calculate(number1: Int, number2: Int) {
when (val result = number1 - number2) {
0 -> println("[DEBUG_LOG] number1 equals number2, result is $result")
in 1..10 -> println("[DEBUG_LOG] result is positive and between 1 and 10: $result")
in -10..-1 -> if (result %2 ==0) {
println("[DEBUG_LOG] result is even and between -10 and -1: $result")
} else {
println("[DEBUG_LOG] result is odd and between -10 and -1: $result")
}
else -> println("[DEBUG_LOG] result is $result")
}
}
在 When 條件判斷式中,加上防衛條件
但是!有時我們需要在條件判斷式內,預先判斷是否能正確執行,當條件成立就執行,而不成立呢?就無法進入執行,避免發生錯誤。 與進入 branch 之後,再使用 if-else
判斷的方式不同,2.2.0 帶來的新語法讓我們可以在進入 branch 之前,預先加上能夠進入的條件,這種判斷方式,也就是 Guard Condition(防衛條件)。
譬如將上方的範例稍作修改,將 -10 ..-1 這個條件,另外加上需要為偶數的條件,換句話說,當數值在 -10 .. -1 這個區間時,只有偶數的情況才會被執行。
fun calculate2(number1: Int, number2: Int) {
when (val result = number1 - number2) {
0 -> println("[DEBUG_LOG] number1 equals number2, result is $result")
in 1..10 -> println("[DEBUG_LOG] result is positive and between 1 and 10: $result")
in -10..-1 if result % 2 == 0 ->
println("[DEBUG_LOG] result is even and between -10 and -1: $result")
else -> println("[DEBUG_LOG] result is $result")
}
}
可以看到,在 in -10..-1
後方,直接加上 if result %2 == 0
,而這就像是下方函式,當數值已經落在 -10 .. -1 之間時,就會進入該函式,而當條件成立時,才能夠執行,如下範例,會進入 if
區間內,並執行裡面的邏輯,不繼續往下執行。
fun checkEvenNumber(result: Int){
if(result % 2 == 0){
println("[DEBUG_LOG] result is even and between -10 and -1: $result")
return
}
}
整理用法
在 when 內的每一個 case 使用防衛條件(Guard Conditions)的用法,如下:
when (expression) {
caseA if conditionA -> { }
caseB if conditionB -> { }
caseC -> { }
else -> { }
}
只需要在 when 的條件後方加上 if
,並加上該條件判斷,就可以加上其防衛條件。 這很像是使用 &&
進行兩個判斷式的聯集。
與在 branch 後方使用 if 判斷式的比較,如下:
若是在 ->
後方 使用 if
,則必須加上 else。
when (expression) {
caseA -> if conditionA {} else { }
caseB -> if conditionB {} else { }
caseC -> { }
else -> { }
}
小結
防衛條件(Guard Conditions),通常用於在函式的最上方判斷帶入的參數、狀態是否正確,使得函式可正常執行,避免到了呼叫的時候,才發現有東西缺少、錯誤導致無法正確呼叫,造成難以後續追查的問題。
在實際執行這個設計模式時,就需要在函式執行前,先確保該函式所需要的條件都已準備好,才能進行後續的呼叫,而有些時候,我們會在不滿足的情況跳出函式,而這也稱為 early return。
將防衛條件加入 Kotlin 的 when 條件判斷式中,需要在每一個 when 的 branch 前方加上 if
判斷式,當條件都吻合時,我們就會進入該 branch 內。
我認為,在 when 後方又加上一層判斷式,那麼這個判斷式很容易被忽略,有可能會造成意想不到的情況。所以在 when 加上防衛條件時,就要特別小心,避免條件不滿足時,會進入 else
branch 中,而該情境是沒有料想到的,那麼就有可能發生錯誤。
Ref:
你的每一個拍手,都是我產出文章的原力。