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)
    }
}

当前回答

可以使用以下方法实现中断:

//Will produce "12 done with nested loop"
//Using "run" and a tag will prevent the loop from running again.
//Using return@forEach if I>=3 may look simpler, but it will keep running the loop and checking if i>=3 for values >=3 which is a waste of time.
fun foo() {
    run loop@{
        listOf(1, 2, 3, 4, 5).forEach {
            if (it == 3) return@loop // non-local return from the lambda passed to run
            print(it)
        }
    }
    print(" done with nested loop")
}

可以通过以下方式实现continue:

//Will produce: "1245 done with implicit label"
fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return@forEach // local return to the caller of the lambda, i.e. the forEach loop
        print(it)
    }
    print(" done with implicit label")
}

正如在座各位所推荐的……阅读文档:P https://kotlinlang.org/docs/reference/returns.html#return-at-labels

编辑: 虽然主要问题是关于forEach的,但重要的是要考虑好的旧“for”。使用Kotlin并不意味着我们需要一直使用forEach。使用古老的“for”是完全可以的,有时甚至比forEach更有表现力和简洁:

fun foo() {
    for(x in listOf(1, 2, 3, 4, 5){
        if (x == 3) break //or continue
        print(x)
    }
    print("done with the good old for")
}

其他回答

这将输出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的代码片段。

你可以使用return from lambda表达式,它模仿了continue或break,这取决于你的用法。

相关问题:在Kotlin的函数循环中,如何执行“中断”或“继续”?

正如Kotlin文档所说,使用return是正确的方法。Kotlin的好处是,如果你有嵌套函数,你可以使用标签显式地写你的返回值来自哪里:

函数范围

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        /** Non-local return directly to the caller of foo(). */
        if (it == 3) return
        print(it)
    }

    println("this point is unreachable")
}

当地的回报

它不会在forEach循环中停止(它就像for循环中的continue)。

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach lit@{
        /** Local return to the caller of the lambda, i.e. the forEach loop. */
        if (it == 3) return@lit
        print(it)
    }

    print(" done with explicit label")
}

看看文档,它真的很好:)

在forEach中继续类型行为

list.forEach { item -> // here forEach give you data item and you can use it 
    if () {
        // your code
        return@forEach // Same as continue
    }

    // your code
}

对于中断类型的行为,你必须使用for in,直到或for in,因为每个列表是可空的或不可空的

对于Nullable列表: For (index in 0 until list.size) { Val item = list[index] //你可以使用数据项了 If () { //你的代码 打破 } //你的代码 } 对于非空列表: For (item in list){//数据项立即可用 If () { //你的代码 打破 } //你的代码 }

也许把forEach改成这样:

for (it in myList) {
    if (condition) {
        doSomething()
    } else {
        break // or continue
    }
} 

它适用于HashMap的:

 for (it in myMap) {
     val k = it.key
     val v = it.value

     if (condition) {
         doSomething()
     } else {
         break // or continue
     }
 }