Loops `科特林的forEach中的break`和continue`

Loops `科特林的forEach中的break`和continue`,loops,foreach,lambda,kotlin,Loops,Foreach,Lambda,Kotlin,Kotlin具有非常好的迭代函数,如forEach或repeat,但我无法使break和continue操作符使用它们(本地和非本地): 我们的目标是用尽可能接近的函数语法模拟通常的循环。在Kotlin的一些旧版本中,这是绝对可能的,但我很难重现语法 问题可能是标签(M12)的错误,但我认为第一个示例无论如何都应该有效 在我看来,我似乎在某个地方读到了一个特殊的技巧/注释,但我找不到关于这个主题的任何参考资料。可能如下所示: public inline fun repeat(times: Int

Kotlin具有非常好的迭代函数,如
forEach
repeat
,但我无法使
break
continue
操作符使用它们(本地和非本地):

我们的目标是用尽可能接近的函数语法模拟通常的循环。在Kotlin的一些旧版本中,这是绝对可能的,但我很难重现语法

问题可能是标签(M12)的错误,但我认为第一个示例无论如何都应该有效

在我看来,我似乎在某个地方读到了一个特殊的技巧/注释,但我找不到关于这个主题的任何参考资料。可能如下所示:

public inline fun repeat(times: Int, @loop body: (Int) -> Unit) {
    for (index in 0..times - 1) {
        body(index)
    }
}
编辑
根据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")
}

原始答案
因为您提供了一个
(Int)->单元
,所以不能中断它,因为编译器不知道它在循环中使用

您几乎没有选择:

使用常规for循环:

for (index in 0 until times) {
    // your code here
}
如果循环是方法中的最后一个代码
您可以使用
return
退出该方法(或者
returnvalue
如果它不是
unit
方法)

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

public inline fun repeatUntil(times: Int, body: (Int) -> Boolean) {
    for (index in 0 until times) {
        if (!body(index)) break
    }
}
根据您的使用情况,您可以使用模仿
继续
中断


这将在相关问题中介绍:

这将打印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)
    }
}
fun main(args:Array){
val nums=listOf(1,2,3,4,5,6,7,8,9,10)
努姆·弗雷奇{
如果(它>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)
    }
}
fun main(args:Array){
val nums=listOf(1,2,3,4,5,6,7,8,9,10)
努姆·弗雷奇{
如果(it==5)return@forEach
println(it)
}
}
在。

尝试,使用
return
是最好的选择。kotlin的好处在于,如果您有嵌套函数,您可以使用标签明确地写下返回的来源:

功能范围返回

fun foo() {
  listOf(1, 2, 3, 4, 5).forEach {
    if (it == 3) return // non-local return directly to the caller of foo()
    print(it)
  }
  println("this point is unreachable")
}
本地返回(它不会停止通过forEach=continuation)


查看文档,这真的很好:)

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

//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")
}
可通过以下方式实现连续性:

//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

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

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

继续
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
}
对于
break
类型行为,您必须使用
for in-until
for in
,根据列表为
Nullable
Non-Nullable

  • 对于可为空的列表:

    for (index in 0 until list.size) {
        val item = list[index] // you can use data item now
        if () {
            // your code
            break
        }
    
        // your code
    }
    
    for (item in list) { // data item will available right away
        if () {
            // your code
            break
        }
    
        // your code
    }
    
  • 对于不可为空的列表:

    for (index in 0 until list.size) {
        val item = list[index] // you can use data item now
        if () {
            // your code
            break
        }
    
        // your code
    }
    
    for (item in list) { // data item will available right away
        if () {
            // your code
            break
        }
    
        // your code
    }
    

  • 嵌套循环forEach()的Break语句:

    结果:

    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 
    

    也许换成

    for(it in myList){
       if(condition){
         doSomething()
       }else{
         break //or continue
        }
    } 
    
    它适用于hashmaps

     for(it in myMap){
         val k = it.key
         val v = it.value
    
           if(condition){
             doSomething()
           }else{
             break //or continue
            }
        }
    
    fun第2部分(操作:列表):Int=ops.asSequence()
    .scan(0){acc,v->acc+v}
    .indexOf(-1)
    
    如果您能够负担得起将集合转换为
    序列
    ,通常成本很低,那么您应该能够利用延迟功能

    您可能已经注意到上面的
    asSequence
    。这是为了拯救我们翻阅整个名单。在我们通过
    indexOf
    进行匹配后,它将立即停止。答对 了保存我们在这里写一个


    如第2部分所述,我有一个完美的解决方案(:


    事实上,我的问题是如何使特定语法起作用,而不是迭代。你不记得在某个Kotlin里程碑上它是可能的吗?我不记得了。但可能是因为我不经常使用“中断并继续”。看,它说“估计-无估计”.
    break
    continue
    只能在循环中工作。
    forEach
    repeat
    和所有其他方法都只是:方法而不是循环。Yoav提出了一些备选方案,但
    break
    continue
    只是不适合在方法中工作。@YoavSternberg辉煌!这就是老文档的和平我一直在寻找!所以这个功能还没有实现,留给将来的版本。如果你想创建一个单独的答案,我会在当前的Kotlin中标记它,你确实可以模仿它(在等待
    continue@label
    break@label
    features),请参阅相关问题:在当前Kotlin中,您确实可以模仿这一点(在等待
    continue@label
    break@label
    功能),请参阅相关问题:此问题可能需要澄清,您是否只询问函数循环是否存在
    中断
    继续
    ,或者您是否正在寻找做完全相同事情的替代答案。前者似乎是这样,因为您拒绝了后者。它们似乎是添加的我在科特林一号上看到了。3@TigranBabajanyan哇!你有链接吗?@voddan,没有,我刚试过,警告:return@lit不停止forEach
    forEach
    ,这是正确的。这是故意的。第一种解决方案是这样做的,但如果循环中有指令,您可以选择返回/跳转到哪里。在第二种情况下,如果我们只使用re转动它就会停止;-)呼叫Return@lit喜欢看电视,但这仍然不是广告
     for(it in myMap){
         val k = it.key
         val v = it.value
    
           if(condition){
             doSomething()
           }else{
             break //or continue
            }
        }
    
      fun part2(ops: List<Int>): Int = ops.asSequence()
        .scan(0) { acc, v -> acc + v }
        .indexOf(-1)
    
    list.apply{ forEach{ item ->
        if (needsToContinue(item)) return@forEach
        if (needsToBreak(item)) return@apply
    }}