在Kotlin中的功能循环中,如何做“休息”或“继续”?

在Kotlin中,我不能在函数循环和lambda中continue breakcontinue ,就像我可以从一个普通的for循环一样。 例如,这不起作用:

 (1..5).forEach { continue@forEach // not allowed, nor break@forEach } 

有一些旧的文档提到这个可用,但它似乎从来没有实现。 当我想要在lambda内continuebreak时,获得相同行为的最佳方法是什么?

注意: 这个问题是由作者故意写的和回答的( 自我回答的问题 ),所以对于常见的Kotlin话题的习惯性的回答是在SO中。 此外,为了澄清一些真正的古老的答案写为科特林的阿尔法,是不是今天的Kotlin准确。

您可以使用lambda表达式的返回,它根据您的使用情况模仿continuebreak

这是一个模仿continue的例子:

 (1..5).forEach { if (it == 3) return@forEach // mimic continue@forEach // ... do something more } 

如果您遇到嵌套或混乱的情况,您可以更加复杂并使用标签:

 (1..3).forEach outer@ { x -> (1..3).forEach inner@ { y -> if (x == 2 && y == 2) return@outer // mimic continue@outer if (x == 1 && y == 1) return@inner // mimic continue@inner // ... do something more } } 

如果你想break你需要一些你可以返回的东西,在这里我们将使用run()函数来帮助我们:

 run breaker@ { (1..20).forEach { x -> if (x == 5) return@breaker // mimic break@forEach // ... do something more } } 

而不是run()它可以是let()apply()或任何你自然拥有的围绕forEach的地方,这是你想要摆脱的地方。 但是你也可以跳过forEach之后的代码块,所以要小心。

这些是内联函数,所以真的不会真正增加开销。

阅读所有特殊情况(包括匿名函数)的Kotlin参考文档,了解返回和跳转 。


这是一个单元测试,证明了这一切的作品:

 @Test fun testSo32540947() { val results = arrayListOf<Pair<Int,Int>>() (1..3).forEach outer@ { x -> (1..3).forEach inner@ { y -> if (x == 2 && y == 2) return@outer // continue @outer if (x == 1 && y == 1) return@inner // continue @inner results.add(Pair(x,y)) } } assertEquals(listOf(Pair(1,2), Pair(1,3), Pair(2,1), Pair(3,1), Pair(3,2), Pair(3,3)), results) val results2 = arrayListOf<Int>() run breaker@ { (1..20).forEach { x -> if (x == 5) return@breaker results2.add(x) } } assertEquals(listOf(1,2,3,4), results2) } 

forEach可以用任何 函数来具体替换:

 (1..20).any { x -> (x == 5).apply { // break on true if (!this) { results2.add(x) } } } 

甚至可能更短:

 (1..20).any { x -> results2.add(x) x == 4 // break on true } 

takeWhile stdlib函数可能被用来代替break。

例如,

 val array = arrayOf(2, 8, 4, 5, 13, 12, 16) array.takeWhile { it % 2 == 0 }.forEach { println(it) } // break on odd array.takeWhile { it % 3 != 0 }.forEach { println(it) } // break on 3 * n 
Interesting Posts