Kotlin有非常好的迭代函数,如forEach或repeat,但我不能使中断和继续操作符与它们一起工作(本地和非本地):
repeat(5) {
break
}
(1..5).forEach {
continue@forEach
}
我们的目标是用函数式语法尽可能地模拟通常的循环。在一些旧版本的Kotlin中,这是绝对可能的,但是我很难重现语法。
问题可能是标签的错误(M12),但我认为第一个示例应该工作。
我好像在什么地方读到过一个特殊的技巧/注释,但我找不到任何关于这个主题的参考资料。可能看起来像下面这样:
public inline fun repeat(times: Int, @loop body: (Int) -> Unit) {
for (index in 0..times - 1) {
body(index)
}
}
forEach():
listOf("a", "b", "c").forEach find@{ i ->
listOf("b", "d").forEach { j ->
if (i == j) return@find
println("i = $i, j = $j")
}
}
结果:
i = a, j = b
i = a, j = d
i = c, j = b
i = c, j = d
带有匿名函数的Continue语句:
listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
if (value == 3) return
print("$value ")
})
结果:
1 2 4 5
forEach():
listOf("a", "b", "c").forEach find@{ i ->
listOf("b", "d").forEach { j ->
if (i == j) return@find
println("i = $i, j = $j")
}
}
结果:
i = a, j = b
i = a, j = d
i = c, j = b
i = c, j = d
带有匿名函数的Continue语句:
listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
if (value == 3) return
print("$value ")
})
结果:
1 2 4 5
如果条件依赖于列表中前一个元素的结果,则可以使用sequence和takeWhile来延迟执行深度优先。
sequenceOf(1, 2, 3, 4, 5).map { i ->
println("i = ${i}")
i < 3
}.takeWhile { success ->
println("success = ${success}")
success
}.toList()
将打印
i = 1
success = true
i = 2
success = true
i = 3
success = false
最后需要终端toList()来执行序列。
详情:https://kotlinlang.org/docs/sequences.html#sequence
这将输出1到5。return@forEach在Java中的作用类似于关键字continue,这意味着在这种情况下,它仍然执行每个循环,但如果值大于5,它会跳到下一个迭代。
fun main(args: Array<String>) {
val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
nums.forEach {
if (it > 5) return@forEach
println(it)
}
}
这将打印1到10,但跳过5。
fun main(args: Array<String>) {
val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
nums.forEach {
if (it == 5) return@forEach
println(it)
}
}
这将输出1到4,当达到5时中断。
fun main(args: Array<String>) {
val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
run breaking@ {
nums.forEach {
if (it == 5) return@breaking
println(it)
}
}
}
链接到ashuges的代码片段。