Android Kotlin中如何优雅地退出循环?

简介: 本文介绍Kotlin中如何在`forEach`循环中提前退出的方法,包括使用`for`循环搭配`break`以及利用标签和`return@标签`的方式。此外,还探讨了标签与`return`、`break`和`continue`在不同场景下的应用,如嵌套循环控制、高阶函数中的提前退出及`inline`函数内的非局部返回等,帮助读者更好地掌握Kotlin的控制流技巧。

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点

Kotlin中如何退出forEach

在 Kotlin 中,forEach 是一个高阶函数,它在遍历集合时会对集合中的每一个元素执行给定的 lambda 表达式。若要在 forEach 中退出循环, return 会返回到外层函数,而不是终止循环。因此,使用 return@forEach 不能达到预期的效果。

合理的做法是使用带标签的 return 或者是使用其他循环结构,如 for 循环。在 forEach 中你可以使用自定义的标签配合 return,以退出循环。

例如:
1、 使用 for 循环:

   val map = hashMapOf("one" to 1, "two" to 2, "three" to 3)

   for ((key, value) in map) {
       if (key == "two") {
           break  // 退出循环
       }
       println("$key -> $value")
   }

2、 使用标签和 forEach

   val map = hashMapOf("one" to 1, "two" to 2, "three" to 3)

   run loop@{
       map.forEach { (key, value) ->
           if (key == "two") {
               return@loop  // 退出循环
           }
           println("$key -> $value")
       }
   }

在这个例子中,run loop@{} 的形式创建了一个标签为 loop 的作用域,然后 return@loop 的作用是退出这个作用域,从而实现直接退出遍历。

其他需要注意的情况

在 Kotlin 中,标签(label)和 returnbreakcontinue 搭配使用的情况,与 Java 有一些区别。除了前面提到的在 forEach 中退出循环的情况,以下是一些其他值得注意的情况:

1. 退出嵌套循环中的控制流

在嵌套循环中,你可以使用标签来方便地控制外层循环的中断或继续,这是 Java 中没有的直接用法。

// Java 中的控制流
outer: for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
        if (j == 5) break outer; // 退出外层循环
    }
}

// Kotlin 中的控制流
outer@ for (i in 0 until 10) {
    for (j in 0 until 10) {
        if (j == 5) break@outer // 退出外层循环
    }
}

2. 带标签的 return退出闭包操作

在高阶函数中,例如 forEachmapfilter 等闭包操作中,如果你需要提前退出,可以使用带标签的 return

在 Kotlin Standard Library 中,如果想中断 forEach 或其他 lambda 表达式,直接 return 会导致外层函数返回,因此需要使用标签。

listOf(1, 2, 3, 4, 5).forEach loop@{
    if (it == 3) return@loop // 退出当前的 lambda 表达式
    println(it)
}
println("Done with forEach")

3. run, with, apply, also 等标准库函数

这类函数也经常用标签配合返回的方式提前中断执行,其中 return 是返回到调用这些函数的上下文,而 return@label 是退出当前作用域。

run myRun@{
    val myList = listOf(1, 2, 3, 4)
    myList.forEach {
        if (it == 3) return@myRun // 退出 run 块
    }
    println("This will not be printed if '3' is found in the list.")
}
println("Outside the run block.")

4. inline 函数与非局部返回

当你在一个 inline 函数内使用 return 时,通常是非局部返回,即返回到调用此 inline 函数的外层函数。

inline fun myInlineFunction(block: () -> Unit) {
    block()
    println("After block")  // 这一行只有在 block 里没有非局部返回时才会执行
}

fun main() {
    myInlineFunction {
        println("Before return")
        return  // 非局部返回到 main 函数
    }
    println("This will not be printed")
}

//上面只会打印:Before return

通过 inline 和非局部返回,你能够在高阶函数中实现类似早期的 goto 的效果,但是更安全、更易懂。

5. 带接收者的 lambda 表达式

在带接收者的 lambda 表达式中,比如适用 withapplyletrun 这样的标准库函数,配合标签时可能运行逻辑会发生变化:

val myStringBuilder = StringBuilder().apply {
    append("Hello, ")
    append("world")
    return@apply // 这将返回 StringBuilder 实例
}

总结:Kotlin 中标签和控制流结合的使用可以帮助开发者更灵活地操控代码的执行流,尤其是在高阶函数和嵌套结构中显现出强大的优势。了解并充分利用这些特性,可以使代码更加简洁易懂,并减少错误。


欢迎关注我的公众号AntDream查看更多精彩文章!

目录
相关文章
|
2月前
|
设计模式 Android开发 Kotlin
Android经典实战之Kotlin委托模式和by关键字
本文介绍了Kotlin中`by`关键字在类及属性委托中的运用,通过实例展示了如何利用类委托简化接口实现,以及如何借助标准与自定义属性委托管理属性的读写操作。通过`by`关键字的支持,Kotlin使得委托模式的实现更为直观且高效。
59 4
|
2月前
|
缓存 安全 Android开发
Android经典实战之用Kotlin泛型实现键值对缓存
本文介绍了Kotlin中泛型的基础知识与实际应用。泛型能提升代码的重用性、类型安全及可读性。文中详细解释了泛型的基本语法、泛型函数、泛型约束以及协变和逆变的概念,并通过一个数据缓存系统的实例展示了泛型的强大功能。
38 2
|
1月前
|
Android开发 Kotlin
Android经典面试题之Kotlin的==和===有什么区别?
本文介绍了 Kotlin 中 `==` 和 `===` 操作符的区别:`==` 用于比较值是否相等,而 `===` 用于检查对象身份。对于基本类型,两者行为相似;对于对象引用,`==` 比较值相等性,`===` 检查引用是否指向同一实例。此外,还列举了其他常用比较操作符及其应用场景。
181 93
|
4天前
|
调度 Android开发 开发者
构建高效Android应用:探究Kotlin多线程优化策略
【10月更文挑战第11天】本文探讨了如何在Kotlin中实现高效的多线程方案,特别是在Android应用开发中。通过介绍Kotlin协程的基础知识、异步数据加载的实际案例,以及合理使用不同调度器的方法,帮助开发者提升应用性能和用户体验。
19 4
|
4天前
|
Java Kotlin 索引
Kotlin12 - 分支与循环
Kotlin 12- 分支与循环
12 2
|
4天前
|
Java Kotlin 索引
Kotlin - 分支与循环
Kotlin - 分支与循环
|
5天前
|
JSON 调度 数据库
Android面试之5个Kotlin深度面试题:协程、密封类和高阶函数
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点。文章详细解析了Kotlin中的协程、扩展函数、高阶函数、密封类及`inline`和`reified`关键字在Android开发中的应用,帮助读者更好地理解和使用这些特性。
10 1
|
12天前
|
Java Kotlin 索引
Kotlin教程笔记(8)- 分支与循环
Kotlin教程笔记(8)- 分支与循环
41 2
|
3天前
|
Java Kotlin 索引
Kotlin教程笔记(9) - 分支与循环
Kotlin教程笔记(9) - 分支与循环
9 0
|
12天前
|
Android开发 Kotlin
Android面试题之Kotlin中如何实现串行和并行任务?
本文介绍了 Kotlin 中 `async` 和 `await` 在并发编程中的应用,包括并行与串行任务的处理方法。并通过示例代码展示了如何启动并收集异步任务的结果。
13 0