Kotlin forEach 中 如何退出循环?

文章讨论了在Kotlin中使用forEach循环时如何退出的问题。通常,`return@forEach`实际上相当于`continue`,不会终止整个循环。由于forEach是内联函数,使用`return`会终止外层函数(如`main`)。要实现类似`break`的效果,可以使用`run`、`let`或`apply`等扩展函数,在其内部的lambda表达式中配合`return@run`来中断forEach循环。

forEach 中 如何退出循环?

上两周本人去面试的时候被问了个问题,就是 forEach 中如何退出循环?我的回答是采用 return 标签的方式,为什么我会这么回答?因为我压根就没有试过在 forEach 中退出循环,平时大多数情况都是使用的 for 循环,使用 breakcontinue 退出循环,今天顺便就记录下这个问题

错误写法

我们来看下下面的代码

fun main() {
    val intList = listOf(1, 2, 3, 4, 5)
    intList.forEach {
        if (it == 3) return@forEach
        println(it)
    }
    println("Foreach end")
}

正常来说,我们都是以为 return@forEach 已经跳出了循环,并且继续执行 println("Foreach end")

我们来看下输出

1
2
4
5
continueForeach end

可以看到,这个 return@forEach 在这里相当于 continue,而不是我们想要的 break

为什么会这样?

我们看下 forEach 是如何实现的

public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
    for (element in this) action(element)
}

高阶内联函数,for 循环遍历。如果对内联函数感兴趣可以康康我的这篇文章 Kotlin inline内联函数

所以我们在 lambda 中使用 return@forEach 会终止 当前这一次 lambda 的执行,并且循环执行下一次 lambda

@forEachforEach 函数的隐式标签,当然你也可以这样,给 forEach 添加一个标签

fun main() {
    val intList = listOf(1, 2, 3, 4, 5)
    intList.forEach label@{
        if (it == 3) return@label
        println(it)
    }
    println("Foreach end")
}

forEach 中的 break

然后当我们头脑发热的时候,又尝试了下面的方法

fun main() {
    val intList = listOf(1, 2, 3, 4, 5)
    intList.forEach{
        if (it == 3) return
        println(it)
    }
    println("Foreach end")
}

来看下输出

1
2

为什么只输出了1、2, 最后的 Foreach end 却没输出?

因为这是内联函数啊,它会将代码拷贝到调用处,这里的 return 会终止 main 函数,官方把这种返回叫做 非局部返回,并且只有在内联函数的 lambda 内部才可以 return ,非内联函数直接就提示错误啦

那么如何实现 break

可以在 forEach 外部在套一层 lambda 表达式,例如这样

fun main() {
    val intList = listOf(1, 2, 3, 4, 5)
    run {
        intList.forEach{
            if (it == 3) return@run
            println(it)
        }
    }
    println("Foreach end")
}

当然你也可以 使用 letapply 等扩展函数

参考文档

有兴趣的可以看下 官方文档

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值