疯狂kotlin讲义连载之流程控制——顺序结构与分支结构 二

193 阅读5分钟

4.2.2 if表达式

Kotlinif还可作为表达式使用,也就是说,整个if表达式(包括else部分)最终会返回一个值,因此if可以代替Java中的三目运算符。

例如如下代码。

程序清单:
codes\04\4.2\IfExpr.kt

fun main(args: Array<String>) {

var age = 20

//if表达式赋值给str变量

var str = if (age > 20) "age大于20" else if(age < 20)

"age小于20" else "age等于20"

println(str)

}

上面粗体字代码示范了将if表达式的值赋值给str变量的情形。从上面代码可以看出,当使用if作为表达式时,由于if表达式必须要有返回值,因此if表达式需要有else部分。

if表达式的分支依然可以是用花括号括起来的代码块,此时代码块的最后一条表达式的值将作为整个代码块的值。例如如下代码。

程序清单:
codes\04\4.2\IfExpr2.kt

fun main(args: Array<String>) {

var age = 18

//if表达式赋值给str变量

var str = if (age > 20) {

println("大于20的分支")

"age大于20"

} else if(age < 20) {

println("小于20的分支")

"age小于20"

} else {

println("else的分支")

"age等于20"

}

println(str)

}

对于上面程序而言,由于age的值为18,因此if表达式将会执行age< 20分支对应的代码块,该代码块最后一条表达式为字符串:"age大于20",因此这条字符串将作为该代码块的值被赋值给
str变量,该程序的执行结果如下。

小于20的分支

age小于20

4.2.3 when分支语句

when分支取代了Java原有的switch语句,例如如下Java程序。

程序清单:
codes\04\4.2\SwitchTest.java

public class SwitchTest{

public static void main(String[] args) {

char score = 'B';

switch(score) {

case 'A':

System.out.println("优秀");

break;

case 'B':

System.out.println("良好");

break;

case 'C':

System.out.println("");

break;

case 'D':

System.out.println("及格");

break;

default :

System.out.println("不及格");

}

}

}

将上面程序改为使用when分支,将会变得更加简洁。程序如下。

程序清单:
codes\04\4.2\WhenTest.kt

fun main(args: Array<String>){

var score = 'B'

when (score){

'A' -> println("优秀")

'B' -> println("良好")

'C' -> println("")

'D' -> println("及格")

else -> println("不及格")

}

}

对于上面两个程序,不难发现when分支其实就是switch分支的简化,when分支的改变有以下几点:

1.不再需要使用case关键字。

2. case值后的冒号改为使用箭头(->)。

3. default改为更为意义更明确的else

提示:正如《疯狂Java讲义》中提到的,switch分支的default是很混淆的——default字面代表“默认”,但switch分支中default其实代表“否则”的意思,when分支将它改为else终于治愈了笔者多年的尴尬。

如果when分支包括多条语句,则需要使用花括号将这些语句包成一个整体形成代码块。例如如下程序。

程序清单:
codes\04\4.2\WhenTest2.kt

fun main(args: Array<String>){

var score = 'B'

when (score){

'A' -> {

println("优秀")

println("望百尺竿头更进步")

}

'B' -> {

println("良好")

println("不拼一把,你不知道自己的能力")

}

'C' -> println("")

'D' -> println("及格")

else -> {

println("不及格")

println("啥也不说了,下次再来")

}

}

}

上面when语句的'A''B'else分支都包含两条语句,因此上面程序要使用花括号将这些语句括起来,形成代码块。运行上面程序可看到如下输出。

良好

不拼一把,你不知道自己的能力

如果when分支只是switch分支的简化,那也不过如此。事实上,when分支比switch分支更强大,下面是when分支的3个小改进:

1. when分支可以匹配多个值。

2. when分支后的值不要求是常量,可以是任意表达式。

3. when分支对条件表达式的类型没有任何要求。

下面先看when分支匹配多个值的程序。

程序清单:
codes\04\4.2\WhenMultiValue.kt

fun main(args: Array<String>){

var score = 'B'

when (score){

'A', 'B' -> {

println("优秀")

println("望百尺竿头更进步")

}

'C', 'D' -> println("")

else -> {

println("不及格")

println("啥也不说了,下次再来")

}

}

}

从上面代码可以看出,当when分支的条件表达式为'A''B'时,都会执行第一个分支;当when
分支的条件表达式为'C''D'时,都会执行第二个分支。运行上面程序可看到如下输出。

优秀

望百尺竿头更进步

when分支后的值不再要求是常量或字面值,可以是任意表达式。例如如下程序。

程序清单:
codes\04\4.2\WhenTest3.kt

fun main(args: Array<String>){

var score = 'B'

var str = "EFGH"

when (score){

str[0] - 4, str[1] - 4 -> {

println("优秀")

println("望百尺竿头更进步")

}

str[2] - 4, str[3] - 4 -> println("")

else -> {

println("不及格")

println("啥也不说了,下次再来")

}

}

}

上面程序的粗体字代码看到各分支的值既不是常量,也不是字面值,而是一个表达式,这在Kotlinwhen分支中完全合适。运行上面程序可看到如下结果。

优秀

望百尺竿头更进步

此外,when分支不再对条件表达式的类型有任何要求,when分支的条件表达式可以是任意类型。例如如下程序。

程序清单:
codes\04\4.2\WhenTypeTest.kt

import java.util.Date

fun main(args: Array<String>){

var date = Date()

// when

分支的条件表达式是Date类型

when (date){

Date() -> {

println("优秀")

println("望百尺竿头更进步")

}

else -> {

println("不及格")

println("啥也不说了,下次再来")

}

}

}

从上面粗体字代码可以看出,此时when分支的条件表达式是Date对象,但这不影响when分支的执行,程序只要when的条件表达式与某个分支的值通过==比较返回true,程序就可以进入执行该分支的代码。

以上内容节选自《疯狂Kotlin讲义》:一本让您最直接认识Kotlin的疯狂讲义


本书即将于2017年11月发售 敬请期待

往期连载

第十九期:juejin.im/post/5a13bc…

相关书籍《疯狂Android讲义》item.jd.com/11689014.ht…