程式碼執行順序是由上往下執行,但是這種方法不可能滿足所有需求,這時候就需要靠一些條件語句(if/else條件語句、when條件語句)或循環語句(for循環、while循環)來控制程式碼該怎麼執行了。
if/else語句和運算式、when運算式可允許開發人員編寫各種條件來控制程式碼在符合或不符合條件的情況下該怎麼運行。
顧名思義,是有條件的執行指定的程式碼,語法是這樣:
if(條件){
//條件成立就執行的事
}else{
//條件不成立要執行的事
}
if()中的條件可以不只一個,可以使用之前說過的邏輯運算子:
接下來都用單一條件來舉例比較容易理解:
比如說,考試分數大於等於60分及格,小於60分不及格,假設分數65分,將考試結果印出在控制台就可以寫這樣:
fun main() {
val score = 65
if (score >= 60){
println("及格")
}else{
println("不及格")
}
//運行結果:及格
}
上例來看的意思是當if()中score>=60
這個條件被滿足時,就會println("及格")
,如果分數是0~59分,就會執行else{}中的println("不及格")
。本例分數是65,所以會執行println("及格")
,應該不難理解。
再看下面這個例子,JoJo跟Dio比成績誰高,平手算Dio贏,贏家的成績將會被記錄在"theBestScore",照上面的模式可能寫出這樣:
fun main() {
val dioScore = 85
val joJoscore = 55
var theBestScore = 0
if (joJoscore > dioScore) {
theBestScore = joJoscore
} else {
theBestScore = dioScore
}
println("The best score is $theBestScore")
}
kotlin 的 if/else 是可以有返回值的,意思是上例可以寫成這樣:
...
var theBestScore = if (joJoscore > dioScore)joJoscore else dioScore
println("The winner's score is $theBestScore")
theBestScore = joJoscore
跟theBestScore = dioScore
的"theBestScore ="也就不需要了。萬一條件分支不只兩個呢?看例子,又是JoJo考試,這次評等更細 ,100 ~ 90 : A等、89 ~ 75 : B等、74 ~ 60 : C等 、小於60 : D等。
JoJo忙著對付Dio,考了個70分:
可以在每層else的分支中繼續再次if/else下去形成巢狀:
val joJoscore = 70
if(joJoscore >= 90){
println("A等")
}else{
if(joJoscore >= 75){
println("B等")
}else{
if(joJoscore >= 60){
println("C等")
}else{
println("D等")
}
}
}
//運行結果:C等
這麼多層是否看得眼花撩亂? 那麼可以再改寫成下面這樣:
將else可以跟下層的if,合寫成 else if分支,可以長出很多else if分支。
if (joJoscore >= 90) {
println("A等")
} else if (joJoscore >= 75) {
println("B等")
} else if (joJoscore >= 60) {
println("C等")
} else {
println("D等")
}
太多else if 分支的時候,有沒有其他寫法? 有的,接著看下去
承上例,也可使用when條件語句。
我們先來講講when條件語句怎麼使用,
//有參數
when(參數){
匹配值 -> {執行程式碼}
.
.
.
else ->{執行程式碼}
}
//或不傳參數
when{
匹配值 -> {執行程式碼}
.
.
.
else ->{執行程式碼}
}
// ->後面{執行程式碼}的{},若只有一行程式碼的話可以省略
知道了基本語法,上面例子可以用when條件語句改寫成:
val joJoscore = 70
when (joJoscore) {
//90..100表示range(包含90、100),遞減的話要寫作 100 downTo 90
in 90..100 -> println("A等")
in 75..89 -> println("B等")
in 60..74 -> println("C等")
else -> println("D等")
}
//或是無參數
when{
joJoscore >= 90 -> println("A等")
joJoscore >= 75 -> println("B等")
joJoscore >= 60 -> println("C等")
else -> println("D等")
}
when按順序將其參數與所有分支匹配,直到滿足某個分支條件。
在分支無法覆蓋所有情況下,else分支是必須要的。
when語句同樣可以像if/else那像有返回值,直接回傳一個值給變數。仍然以成績等第為例,將JoJo成績存入 level變數中可以寫成這樣:
//上面任一種寫法都可,println()就可以提取出來列印level這儲存了結果的變數即可。
val level = when (joJoscore) {
in 90..100 -> "A等"
in 75..89 -> "B等"
in 60..74 -> "C等"
else -> "D等"
}
println("level: $level")
如果貴族JoJo每天都有自己的luckyColor需要配合穿搭,但有些天會重複,如週一、三、五紅色、周二、四:藍色、週六、日:綠色,這樣條件依照剛剛學的不就會有週一到週日7個分支?
var daysOfTheWeek = "Monday"
val luckyColor = when(daysOfTheWeek){
"Monday" -> "red"
"Tuesday" -> "blue"
"Wednesday" -> "red"
"Thursday" -> "blue"
"Friday" -> "red"
"Saturday" -> "green"
"Sunday" -> "green"
else -> "再說一次,星期幾^^?"
}
println("$daysOfTheWeek luckyColor : $luckyColor") // 結果:Monday luckyColor : red
這樣也太囉嗦了吧,when可以再將同樣結論的匹配條件以「,」隔開寫成:
var daysOfTheWeek = "Monday"
val luckyColor = when(daysOfTheWeek){
"Monday","Wednesday","Friday" -> "red"
"Tuesday","Thursday", -> "blue"
"Saturday", "Sunday" -> "green"
else -> "再說一次,星期幾^^?"
}
println("$daysOfTheWeek luckyColor : $luckyColor")
喔耶
但是每次都要使用else,但有時候else帶來很多困擾,比如,星期明確就是一到日,哪來的else?,這時候,也可以使用enum class或sealed class,將所有情形列出,讓when 知道這已經是所有的情況,就不需要使用else囉
如:
//enum class 是用來儲存常數的列舉類別
enum class DaysOfTheWeek{
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
fun main() {
var today = DaysOfTheWeek.FRIDAY
val luckyColor = when(today){
DaysOfTheWeek.MONDAY, DaysOfTheWeek.WEDNESDAY, DaysOfTheWeek.FRIDAY -> "red"
DaysOfTheWeek.TUESDAY,DaysOfTheWeek.THURSDAY -> "blue"
DaysOfTheWeek.SATURDAY,DaysOfTheWeek.SUNDAY -> "green"
}
println("$today Lucky Color : $luckyColor")
//結果: FRIDAY Lucky Color : red
}
T.G.I.F.,明天見。