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

当前回答

正如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")
}

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

其他回答

编辑: 根据Kotlin的文档,可以使用注释来模拟继续。

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

如果您想模拟中断,只需添加一个运行块

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

最初的回答: 因为你提供了一个(Int) ->单元,你不能中断它,因为编译器不知道它是在循环中使用的。

你有几个选择:

使用常规的for循环:

for (index in 0 until times) {
    // your code here
}

如果循环是方法中的最后一个代码 您可以使用return来退出方法(如果不是单元方法,则返回值)。

使用方法 创建一个自定义重复方法,该方法返回用于继续的布尔值。

public inline fun repeatUntil(times: Int, body: (Int) -> Boolean) {
    for (index in 0 until times) {
        if (!body(index)) break
    }
}

正如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 () { //你的代码 打破 } //你的代码 }

fun part2(ops: List<Int>): Int = ops.asSequence()
    .scan(0) { acc, v -> acc + v }
    .indexOf(-1)

如果能够负担得起将集合转换为序列的费用(通常成本很小),那么应该能够利用延迟特性。

您可能已经注意到上面的asSequence。这是为了让我们不去看整个名单。在我们通过indexOf得到匹配后,它就会停止。宾果!省得我们在这里写一会儿。

在第二部分的媒体文章。

我有一个完美的解决方案(:

list.apply{ forEach{ item ->
    if (willContinue(item)) return@forEach
    if (willBreak(item)) return@apply
}}