提到 when,大家都會(huì)聯(lián)想到 Java 中的 switch燃领,然而在 kotlin 中士聪,when 顯然比 Java 中的 switch 要強(qiáng)大得多。首先猛蔽,我們先來看看 when 的特點(diǎn):
- 它可以作為表達(dá)式使用
- 使用更加安全
- 強(qiáng)大靈活的分支結(jié)構(gòu)
- 可以不帶參數(shù)
接下來剥悟,我來帶大家逐步領(lǐng)略這些特點(diǎn)。以下面這段 Java 功能代碼為例:
switch(animal) {
case EAGLE:
System.out.println("鳥類");
break;
case DOLPHIN:
System.out.println("獸類");
break;
case LOCUST:
System.out.println("昆蟲類");
break;
case CARP:
System.out.println("魚類");
break;
case TIGER:
System.out.println("獸類");
break;
case DUCK:
System.out.println("鳥類");
break;
default:
System.out.println("未知?jiǎng)游?);
break;
}
從以上代碼可以看出曼库,我們這里實(shí)現(xiàn)的功能是:通過用戶輸入一個(gè)動(dòng)物名稱來得到其對(duì)應(yīng)的種類信息区岗。乍一看,你可能會(huì)覺得上面的代碼再正常不過毁枯,但是倘若我們的輸入情形很多的話慈缔,就會(huì)增加密密麻麻的限制條件,這肯定是我們不想看到的种玛。那么藐鹤,讓我們來看看通過 Kotlin 的 when 表達(dá)式如何實(shí)現(xiàn)相同功能:
when(animal) {
EAGLE, DUCK -> println("鳥類")
DOLPHIN, TIGER -> println("獸類")
CARP -> println("魚類")
LOCUST -> println("昆蟲類")
else -> println("未知?jiǎng)游?)
}
OK,以上就是該功能代碼的 kotlin 實(shí)現(xiàn)方式赂韵,代碼不僅簡(jiǎn)化了很多娱节,也省去了大量的 break 語句,避免了 Java 中因遺漏 break 而導(dǎo)致的 bug右锨,增強(qiáng)了安全性括堤。如果匹配成功,對(duì)應(yīng)的分支便會(huì)執(zhí)行绍移,同時(shí)也可以把多個(gè)情況合并到同一個(gè)分支悄窃,只需要通過逗號(hào)隔開,并沒有額外的代碼蹂窖。
PS:每個(gè)條件分支的處理通過在 -> 之后來進(jìn)行轧抗。
作為表達(dá)式使用
首先,我們需要重溫一下表達(dá)式與語句的區(qū)別瞬测。表達(dá)式有值横媚,并能作為另一個(gè)表達(dá)式的一部分來使用;而語句沒有返回值月趟。Java 中的控制結(jié)構(gòu)皆為語句灯蝴。而在 Kotlin 中,除了循環(huán)體結(jié)構(gòu)外孝宗,大多數(shù)控制結(jié)構(gòu)都是表達(dá)式穷躁。舉個(gè)栗子??,還是上面的例子因妇,我們可以將其優(yōu)化為以下代碼:
var result = when(animal) {
EAGLE, DUCK -> "鳥類"
DOLPHIN, TIGER -> "獸類"
CARP -> "魚類"
LOCUST -> "昆蟲類"
else -> "未知?jiǎng)游?
}
// 輸入:DUCK问潭,返回:當(dāng)前動(dòng)物的種類為:鳥類
println("當(dāng)前動(dòng)物的種類為: $result")
此外,我們也可以直接通過表達(dá)式函數(shù)來直接得到最終的結(jié)果:
fun displayAnimalType(animal: Animal) =
when(animal) {
Animal.EAGLE, Animal.DUCK -> "鳥類"
Animal.DOLPHIN, Animal.TIGER -> "獸類"
Animal.CARP -> "魚類"
Animal.LOCUST -> "昆蟲類"
else -> "未知?jiǎng)游?
}
強(qiáng)大靈活的分支
Kotlin 中的 when 遠(yuǎn)比 Java 當(dāng)中的 switch 要強(qiáng)大得多婚被。switch 只能以常量作為分支條件狡忙,而 when 允許使用任意對(duì)象。emmm~舉個(gè)簡(jiǎn)單的例子吧:
fun handleResult(score: Int) =
when(score) {
in 0..39 -> "fail to go up to the next grade."
in 40 until 60 -> "not pass, should test again."
97,98,99,100 -> "learning outstanding results."
else -> "pass the test."
}
Java 當(dāng)中址芯,當(dāng)我們的分支情況比較多或者每種分支可能會(huì)重復(fù)多次時(shí)灾茁,勢(shì)必會(huì)通過 if-else 來各種判斷,而在 Kotlin 當(dāng)中谷炸,一個(gè) when 就能幫我們完成這些操作删顶。
此外,如果你想判斷一個(gè)未知變量的類型淑廊,而其可能類型有很多種可能性逗余,那么也可以通過 when 來實(shí)現(xiàn),例如:
fun judgeAnimalKind(animal: Any) =
when(animal) {
is Bird -> "這是鳥類"
is Fish -> "這是魚類"
judgeIfInsect(animal) -> "這是昆蟲"
else -> "我不知道這是什么動(dòng)物"
}
當(dāng)然季惩,我們也可以將代碼塊作為我們的分支體录粱,這時(shí)候,代碼塊中最后一個(gè)表達(dá)式或者變量就是該分支體的返回結(jié)果画拾,如:
fun judgeAnimalKind(animal: Any) =
when(animal) {
is Bird -> "這是鳥類"
is Fish -> "這是魚類"
judgeIfInsect(animal) -> "這是昆蟲"
else -> {
val kind = if (judgeDolphin(animal) || judgeTiger(animal)) {
"這是獸類"
}else {
"我不知道這是什么動(dòng)物"
}
kind
}
}
上述代碼中啥繁,kind 即為我們的 else 分支塊中的最終返回結(jié)果。
無參的情況
特別地青抛,when 中的參數(shù)可能并非滿足我們的需求旗闽,我們可以選擇省略該參數(shù),例如這樣:
when {
phoneNumber?.length != 11 -> toast("illegal phone number.")
password.isNullOrEmpty() -> toast("please input password")
}
總結(jié)
通過以上的介紹,我們不難發(fā)現(xiàn):when 的使用場(chǎng)景要比 Java 的 switch 靈活适室、強(qiáng)大的多嫡意,同時(shí),我們也可以借助 when 來重構(gòu)和優(yōu)化復(fù)雜的 if-else 結(jié)構(gòu)捣辆,以簡(jiǎn)化我們的代碼蔬螟,提高代碼的可讀性。