forEach
中 如何退出循环?上两周本人去面试的时候被问了个问题,就是 forEach
中如何退出循环?我的回答是采用 return 标签的方式,为什么我会这么回答?因为我压根就没有试过在 forEach
中退出循环,平时大多数情况都是使用的 for
循环,使用 break
和 continue
退出循环,今天顺便就记录下这个问题
我们来看下下面的代码
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
@forEach
是 forEach
函数的隐式标签,当然你也可以这样,给 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")
}
当然你也可以 使用 let
, apply
等扩展函数
有兴趣的可以看下 官方文档