crazyandcoder

面向Android开发者kotlin教程(3-流程控制)

2021.07.12

Kotlin流程控制.png

1 前言

每一门语言它都会涉及到基本的流程控制,kotlin 也不例外,kotlin 常用的流程控制主要有分支语句,循环语句,跳转语句。

2 分支语句

在 kotlin 中分支语句主要是 if,when 语句。

2.1 if

在 Kotlin 中,if是一个表达式,即它会返回一个值。 因此就不需要三元运算符(条件 ? 然后 : 否则),因为普通的 if 就能胜任这个角色。if-else 语句是控制程序流程的最基本的形式,其中 else 是可选的。在 Kotlin 中,if 是一个表达式,即它会返回一个值。

fun main(args: Array<String>) {
    println(max(1, 2))
}
fun max(a: Int, b: Int): Int {
// 作为表达式
    val max = if (a > b) a else b
    return max //  return if (a > b) a else b
}
fun max1(a: Int, b: Int): Int {
    // 传统用法
    var max1 = a
    if (a < b) max1 = b
    return max1
}
fun max2(a: Int, b: Int): Int {
// With else
    var max2: Int
    if (a > b) {
        max2 = a
    } else {
        max2 = b
    }
    return max2
}

另外,if 的分支可以是代码块,最后的表达式作为该块的值,if 作为代码块时,最后一行为其返回值。

fun max3(a: Int, b: Int): Int {
    val max = if (a > b) {
        print("Max is a")
        a
    } else {
        print("Max is b")
        b
    }
    return max
}

如果 if 表达式只有一个分支, 或者分支的结果是 Unit , 它的值就是 Unit 。

>>> val x = if(1==1) true
>>> x
kotlin.Unit

>>> val y = if(1==1) true else false
>>> y
true

2.2 when

when 表达式类似于 switch-case 表达式。when 会对所有的分支进行检查直到有一个条件满足。但相比 switch 而言,when 语句要更加的强大,灵活。when 将它的参数与所有的分支条件顺序比较,直到某个分支满足条件。 when 既可以被当做表达式使用也可以被当做语句使用。如果它被当做表达式, 符合条件的分支的值就是整个表达式的值,如果当做语句使用, 则忽略个别分支的值。如果其他分支都不满足条件将会求值 else 分支。 如果 when 作为一个表达式使用,则必须有 else 分支。


fun when_case(obj: Any) {
    when (obj) {
        1 -> print("第一项")
        "hello" -> print("这个是字符串hello")
        is Long -> print("这是一个Long类型数据")
        !is String -> print("这不是String类型的数据")
        else -> print("else类似于Java中的default")
    }
}

像 if 一样,when 的每一个分支也可以是一个代码块,它的值是块中最后的表达式的值。如果其他分支都不满足条件会到 else 分支(类似 default)。如果我们有很多分支需要用相同的方式处理,则可以把多个分支条件放在一起,用逗号分隔:

fun switch(x: Any) {
    when (x) {
        -1, 0 -> print("x == -1 or x == 0")
        1 -> print("x == 1")
        2 -> print("x == 2")
        else -> { 
	    // 注意这个块
            print("x is neither 1 nor 2")
        }
    }
}

3 循环语句

3.1 for

for 循环可以对任何提供迭代器(iterator)的对象进行遍历,这相当于像 java 这样的语言中的 foreach 循环。语法如下:

for (item in collection) {
    print(item)
}

同时,也可以通过索引遍历一个数组或者一个 list

for (i in array.indices) {
    print(array[i])
}

因此,for 可以循环遍历任何提供了迭代器的对象。即:

  1. 有一个成员函数或者扩展函数 iterator(),它的返回类型
  2. 有一个成员函数或者扩展函数 next(),并且
  3. 有一个成员函数或者扩展函数 hasNext() 返回 Boolean。

3.2 while

while 和 do .. while使用方式跟C、Java语言基本一致。

fun main(args: Array<String>) {
    var x = 10
    while (x > 0) {
        x--
        println(x)
    }
    var y = 10
    do {
        y = y + 1
        println(y)
    } while (y < 20) 
}

4 跳转语句

Kotlin 有三种结构化跳转表达式:

  1. return。默认从最直接包围它的函数或者匿名函数返回。
  2. break。终止最直接包围它的循环。
  3. continue。继续下一次最直接包围它的循环。

4.1 break

break 表示当条件满足时就会结束循环,而不是等到循环条件为 false 时停止。跟 Java 一样。

fun break_test() {
    for (i in 1..10) {
        println(i)
        if (i % 2 == 0) {
            break
        }
    } 
}
//打印结果:1.2

从 1 到 10 开始遍历,当第一个是 2 的倍数时,停止遍历,退出循环。

4.2 contine

continue 正好跟 break 相反,它只是在条件满足时结束当前的循环,然后从下个开始继续循环。

fun continueDemo() {
    for (i in 1..10) {
        if (i % 2 == 0) {
            continue
        }
        println(i)
    }
}
//打印结果:1.3.5.7.9

4.3 return

在 Kotlin 中,除了表达式的值,有返回值的函数都要求显式使用 return 来返回其值。

fun sum(a: Int,b: Int): Int{
    return a+b
}

可以直接使用=符号来直接返回一个函数的值。

>>> fun sum(a: Int,b: Int) = a + b
>>> fun max(a: Int, b: Int) = if (a > b) a else b

4.4 throw

在 Kotlin 中 throw 是表达式,它的类型是特殊类型 Nothing。 该类型没有值。如果把一个 throw 表达式的值赋值给一个变量,需要显式声明类型为Nothing:

>>> val ex = throw Exception("YYYYYYYY")
error: 'Nothing' property type needs to be specified explicitly
val ex = throw Exception("YYYYYYYY")
    ^
>>> val ex:Nothing = throw Exception("YYYYYYYY")
java.lang.Exception: YYYYYYYY