Kotlin流程控制语句

文章结构:

  • 分支语句(if、when)
  • 循环语句(for、while)
  • 跳转语句(break、continue、return、label、throw)

分支语句(if、when)

if 表达式

  • 在kotlin中 if是一个表达式,它会返回一个值
    • if分支可以是代码块,最后的表达式作为该块的值(最后一行为其返回值)
fun main(args: Array) {
    println("hello kotlin !")
    println(max(2,9))
    println(max2(2,9))

    println("facts(2) = ${facts(2)}")
    println("facts(10) = ${facts(10)}")
}

fun max(x: Int, y: Int): Int {
    return if (x > y) x else y
}

fun max2(x: Int, y: Int): Int {
    val max = if (x>y) {
        println("max is x")
        x			// 最后的表达式作为该块的值
    } else {
        println("max is y")
        y			// 最后的表达式作为该块的值
    }
    return max
}

/**
 * 阶乘函数
 */
fun facts(n: Int): Int {
    return if (n <= 1) 1 else n * facts(n - 1)
}
  • 在kotlin中没有类似Java的三元表达式true?1:0,对应的写法是if...else语句

if后的括号不能省略,括号中的表达式值必须是布尔型。

 

when 表达式

when 表达式类似于 switch...case表达式;
when 会对所有分支进行检查,直到有一个条件满足

fun main(args: Array) {
    whenFx(3)
    whenFx('U')
    whenFx("hello")
    whenFx("world")

    whenFy(3)
    whenFy(10)
    whenFy(23)
    whenFy(30)
    whenFy(60)
    whenFy(-1)

    println("${fact(2)}")
    println("${fact(10)}")
}

fun whenFx(x: Any?): Unit {
    when(x) {
        // 如果很多分支需要相同的处理方式,那么可以把多个分支条件放在一起,用逗号分隔:
        0,1,2,3,4,5 -> println("$x 是一个 0~5 之间的整数")

        is Char -> println("$x 是一个 Char类型的数据")
        "hello" -> println("$x 是一个 字符串hello")
        else -> println("[$x] else 类似于 java switch...case 中的 default.")
    }
}

/**
 * 检测一个值是否在某个区间/集合中
 */
fun whenFy(x: Int): Unit {
    val validNum = arrayOf(1,2,3)
    when(x) {
        in validNum -> println("$x 在集合(1,2,3)中")
        in 1..10 -> println("$x 在范围 1..10 中")
        !in 10..30 -> println("$x 不在范围 10..30 中")
        else -> println("$x , default..")
    }
}

/**
 * 阶乘函数
 */
fun fact(n: Int): Int {
    var data = -1;
    data = when(n) {
        0,1 -> 1
        else -> n* fact(n-1)
    }
    return data;
}

 

循环语句(for、while)

for循环

for循环可以对任何提供迭代器的对象进行遍历。

iterator

fun main(args: Array) {
    forInArray()
    forInRange()
}

fun forInArray(): Unit {
    val arr = arrayOf(1,2,4,8,16)
    // for in 循环
    for (x in arr) {
        println(x)
    }

    for (i in arr.indices) {
        // arr.indices 持有数组的下标列表
        println("$i , ${arr[i]}")
    }

    for ( (index,value) in arr.withIndex() ) {
        // arr.withIndex() 函数持有数组的(下标,值)列表
        println("$index : $value")
    }
}

/**
 * 范围表达式中使用 for循环
 */
fun forInRange(): Unit {
    for (i in 10..20) {
        println(i)
    }

    // 等价于
    (10..20).forEach { x ->
        println("item: $x")
    }
}

while循环

while 和 do...while循环语句的使用方法与C、Java语言基本一致。

fun main(args: Array) {
    println("while: ")
    whileF()
    println("\ndo...while: ")
    doWhileF()
}

fun whileF(): Unit {
    var x = 10
    while (x>5) {
        x--
        print("$x  ")
    }
}

fun doWhileF(): Unit {
    var y = 10
    do {
        y++
        print("$y  ")
    } while (y<1)
}

跳转语句(break、continue、label、return、throw)

break、continue

breakcontinue 语句都是用来控制循环结构的,用来停止循环/中断跳转。

  • break 语句用于完全结束一个循环,直接跳出循环体;
  • continue 语句用于终止本轮循环,但还是会继续下一轮循环;

 

return 语句

  1. 有返回值的函数都要求显式使用return 语句返回其值。
  2. 函数字面量:kotlin中可以直接使用“=”符号返回一个函数的值,这样的函数称为‘函数字面量’。
fun main(args: Array) {
    val r= sum(1,3)
    println(r)
    println(sumF(5,5)) // 输出:() -> kotlin.Int,sumF(5,5)的返回值是一个函数,即 () -> kotlin.Int
    println(sumF(5,5).invoke()) // 输出:10,invoke()函数实现sumF函数的调用
    println(sumF(5,5)())    // 输出:10,()运算符的作用等价于invoke()函数

    println(sumF2(5,15)) // 输出:() -> kotlin.Int,
    println(sumF2(5,15).invoke()) // 输出:20
    println(sumF2(5,15)()) // 输出:20 
}

// 使用表达式声明sum()函数
fun sum(x: Int, y: Int) = x+y

// 使用fun关键字声明了一个匿名函数,同时直接使用表达式来实现函数
// { x+y } 的类型是 () -> kotlin.Int 函数;{ x+y }表达式返回的是一个Lambda表达式
// ⚠️  x+y 与 { x+y } 的区别
val sumF = fun(x: Int, y: Int) = { x+y }

// 使用表达式声明 sumF2()函数,{}表示一个Lambda表达式
// ⚠️  x+y 与 { x+y } 的区别
fun sumF2(x: Int, y: Int) = { x + y };
  1. kotlin中的return语句 与 lambda表达式中的return语句的区别
  • kotlin中的return语句会从最近的函数(或匿名函数)中返回 (类似循环体中continue语句效果)
  • lambda表达式中的return语句 直接返回到最近的外层函数 (类似循环体中break语句效果)
fun returnInKotlinVsLambda(): Unit {
    val arr = intArrayOf(1,2,3,4,5) // 声明一个Int数组
    println("return in kotlin function:")
    arr.forEach (
        fun(x: Int) { // 给forEach传入一个函数,该函数中的return语句不会跳出forEach
            if (x == 3) return // 类似循环体中continue语句效果
            println(x) // 输出:1,2,4,5
        }
    )

    println("return in kotlin lambda:")
    arr.forEach { 
        // 在lambda表达式中的return语句 直接返回到最近的外层函数
        if (it == 3) return //类似循环体中break语句效果
        println(it) // 输出:1,2
    }
}

 

Label标签

使用Label标签来控制 return、break、continue语句的跳转行为。
任何表达式都可以使用Label标签来标记。

fun labelF(): Unit {
    val arr = intArrayOf(1,2,3,4,5) // 声明一个Int数组
    println("显式标签:")
    arr.forEach jump@ { // jump@  是一个标签
        if (it == 3) return@jump // 执行跳转到lambda表达式标签 jump@ 处,继续forEach循环
        println(it) // 输出:1,2,4,5
    }

    println("隐式标签:")
    arr.forEach { // 隐式标签 与接收该lambda的函数同名
        if (it == 3) return@forEach // 返回@forEach 处,继续下一个循环
        println(it) // 输出:1,2,4,5
    }
}

 

throw

kotlin中throw是表达式,它的类型是特殊类型 Nothing
Nothing类型没有值,与C、Java中的void一样。

fun main(args: Array) {
    // 使用 :: 类引用操作符,返回Nothing的类型
    // 输出:class java.lang.Void
    println("${Nothing::class}")

    fail("param type is error !")
}

fun fail(x: String): Nothing {
    throw IllegalArgumentException(x)
}

 

知识点参考:《Kotlin从入门到进阶实战》陈光剑 

你可能感兴趣的:(Kotlin系列,kotlin,开发语言,android)