Kotlin 控制流(二):返回和跳转

Kotlin 控制流(一):条件和循环

Kotlin 中有三个结构跳转表达式:

  • 默认情况下,return 会从最近的外层函数或匿名函数中返回。

  • break会终止最近的循环

  • continue 会继续执行最近的外层循环的下一次迭代

这些表达式可以作为更大的表达式的一部分:

kotlin 复制代码
val s = person.name ?: return

这些表达式是Nothing类型

Break and continue 标签

在 Kotlin 中所有的表达式都可以标记一个标签,标签由@标记,比如abc@ 或者 fooBar@。使用的时候只需要把标签写在表达式的前面即可。

kotlin 复制代码
loop@ for (i in 1..100) {
    // ...
}

现在,可以使用标签来限定 break 或者 continue 的作用范围:

kotlin 复制代码
loop@ for (i in 1..100) {
    for (j in 1..100) {
        if (...) break@loop
    }
}

用标签限定的 break 会跳转到被该标签标记的循环之后的执行点;而用标签限定的 continue 则会继续执行被该标签标记的循环的下一次迭代。

举个例子吧:

kotlin 复制代码
outerLoop: for (let i = 0; i < 3; i++) {
  console.log(`外层循环 i = ${i}`);
  innerLoop: for (let j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      break outerLoop; // 跳转到 outerLoop 循环之后
      // continue outerLoop; // 直接进入 outerLoop 的下一次迭代(i 变为 2)
    }
    console.log(`  内层循环 j = ${j}`);
  }
}
console.log("循环结束");

循环结束的时候 i 是 1,不是 2。

Return 标签

在 Kotlin,可以通过函数字面量、局部函数和对象表达式来实现函数嵌套。带限定符的 return 允许开发者从外层函数中返回。

带标签的返回最重要的使用场景是从 lambda 表达式返回。可以给 lambda 表达式添加标签,然后通过 return 来限定作用范围:

kotlin 复制代码
fun foo() {
    listOf(1, 2, 3, 4, 5).forEach lit@{
        if (it == 3) return@lit // local return to the caller of the lambda - the forEach loop
        print(it)
    }
    print(" done with explicit label")
}
//1245 done with explicit label
仅仅是return了lit

一般情况下,使用隐式标签会更便捷,因为这类标签与接收该 lambda 的函数同名。

kotlin 复制代码
fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return@forEach // local return to the caller of the lambda - the forEach loop
        print(it)
    }
    print(" done with implicit label")
}
1245 done with implicit label
仅仅是return了forEach

当然了,也可以返回匿名函数,作用同上。

上面的局部 return 的用法,与常规循环中 continue 的作用类似。

目前没有与 break 直接对应的语法,但可以通过添加一个外层的 run lambda,并从该 lambda 中进行非局部返回来模拟 break 的效果:

kotlin 复制代码
fun foo() {
    run loop@{
        listOf(1, 2, 3, 4, 5).forEach {
            if (it == 3) return@loop // non-local return from the lambda passed to run
            print(it)
        }
    }
    print(" done with nested loop")
}
//12 done with nested loop
直接将loop返回

此处之所以能实现非局部返回,是因为嵌套的 forEach() 所接收的 lambda 是作为内联函数(inline function) 运行的。

当需要返回一个值时,语法解析器会优先识别带限定符的 return(qualified return)(即 return@标签名 形式),而非默认的穿透式 return。

kotlin 复制代码
return@a 1

这意味着 "在标签 @a 处返回值 1",而非 "返回一个带标签的表达式 (@a 1)"。

kotlin 复制代码
fun example() {
    val result = listOf(1, 2, 3).map a@{  // map 会处理 lambda 的返回值
        if (it == 2) {
            return@a 100  // 在 @a 标签处返回 100(仅退出当前 lambda,作为 map 的转换结果)
        }
        it  // 其他元素保持原值
    }
    println(result)  // 输出:[1, 100, 3]
}

原文

相关推荐
Jasonakeke3 小时前
【重学 MySQL】九十二、 MySQL8 密码强度评估与配置指南
android·数据库·mysql
Mertrix_ITCH3 小时前
在 Android Studio 中修改 APK 启动图标(2025826)
android·ide·android studio
荏苒追寻3 小时前
Android OpenGL基础1——常用概念及方法解释
android
人生游戏牛马NPC1号4 小时前
学习 Android (十七) 学习 OpenCV (二)
android·opencv·学习
恋猫de小郭4 小时前
谷歌开启 Android 开发者身份验证,明年可能开始禁止“未经验证”应用的侧载,要求所有开发者向谷歌表明身份
android·前端·flutter
用户094 小时前
Gradle声明式构建总结
android
用户095 小时前
Gradle插件开发实践总结
android
Digitally15 小时前
如何将视频从安卓设备传输到Mac?
android·macos
alexhilton17 小时前
Compose Unstyled:Compose UI中失传的设计系统层
android·kotlin·android jetpack