当前位置: 首页 > 知识库问答 >
问题:

在Kotlin中的一个函数循环中,我如何做一个“中断”或“继续”?

吕寒
2023-03-14

在Kotlin中,我不能在函数循环和我的lambda中执行breakcontinue--就像我在普通的for循环中一样。例如,这不起作用:

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

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

注意:这个问题是作者有意编写和回答的(自我回答的问题),因此通常被问到的Kotlin主题的惯用答案出现在so中。也是为了澄清一些为科特林的阿尔法写的真正古老的答案,这些答案对当今的科特林来说并不准确。

共有1个答案

黄弘盛
2023-03-14

除了您所要求的之外,还有其他选项提供类似的功能。例如:

可以避免使用筛选器:(例如continue)处理某些值

dataSet.filter { it % 2 == 0 }.forEach {
    // do work on even numbers
}

您可以通过使用takewhile:(类似于break)来停止函数循环

dataSet.takeWhile { it < 10 }.forEach {
    // do work on numbers as long as they are < 10, otherwise stop
}
dataSet.asSequence()
       .takeWhile { it >=  0 }    // a -1 signals end of the dataset (break)
       .map { it + 1 }            // increment each number
       .filterNot { it % 5 == 0 } // skip (continue) numbers divisible by 5
       .map { it - 1 }            // decrement each number by 1
       .filter { it < 100 }       // skip (continue) if number is >= 100
       .drop(5)                   // ignore the first 5 numbers
       .take(10)                  // use the next 10 numbers and end
       .forEach {
           // do work on the final list
       }

下面是一个模拟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
    }
}

下面的单元测试证明了这一切都是有效的:

@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)
}
 类似资料:
  • 问题内容: 我一直在尝试为JavaScript中动态创建的“ a”标签的onclick事件分配一个函数。所有标记均按如下所示循环创建: 所有四个链接的警报值始终为“ 4”。很明显。谷歌搜索时,我遇到了显示以下代码片段的帖子: 我设法根据需要对其进行了调整,并使alert(i)正常工作,但是如果有人可以确切解释以上代码的作用,我将不胜感激。 问题答案: 当您将功能分配给单击处理程序时,将创建一个闭包

  • 问题内容: 我有四个foreach循环,这些循环遍历集合并根据条件进行操作。 这是我现在正在编写的代码: 主要对象(代码中的对象)来自第三方提供程序SDK,因此我无法在该部分上进行任何更改。我想问一下Stack Overflow社区是否有更好的方法来打破所有四个foreach循环。或者,如果还有其他方法可以重构此代码,使其更具可读性和可维护性。 问题答案: 在最外面的循环上使用标签,当您想跳出所有

  • 问题内容: 我想知道是否有任何内置方法可以继续进行python外循环中的下一次迭代。例如,考虑以下代码: 我希望此继续语句退出jj循环并转到ii循环中的下一项。我可以通过其他方式(通过设置标志变量)来实现此逻辑,但是有一种简单的方法可以做到这一点,还是像要求太多? 问题答案: 在一般情况下,当您有多个循环级别且对您不起作用时(因为您要继续上一个循环,而不是当前循环的右上循环),可以执行以下操作之一

  • 因此,我正在开发一个程序,允许用户将学生添加到班级中,并管理他们的成绩等等。当用户选择菜单中的第一个选项时,他必须输入一个id(必填),但他也可以添加数字分数和/或字母等级。根据另一篇文章中的反馈,我设法创建了一个字符串变量行来读取用户输入,然后检查它是否为“S”/“S”(跳过或不跳过),并相应地将值解析为double。现在基于这个问题,如果用户决定跳过添加分数,我如何跳过提示并继续下一个提示?我

  • 我有一个类(称为name),它有如下不同的方法: alex(), john(), claire(), charles(), luke(), richard(), jen()等等 我需要逐一调用所有这些方法,例如: ... 等等 我尝试的是创建一个名称列表,并调用循环中的所有方法 但这种调用方法的方式正在失败。有没有办法在循环中调用同一类的多个方法?

  • 我正在MST上的CLRS中尝试ch23,这里有一个问题: 给定一个图G和一个最小生成树T,假设我们减少不在T中的一条边的权重。给出了在修改图中求最小生成树的算法。 我找到的一个解决方案是在中添加此新更改的边,然后在T中创建一个简单的循环,遍历此循环并删除此循环中的最大权重边,瞧,找到了新更新的MST! 我的问题是,如何在这个简单循环中只遍历节点?因为如果我在中从这个新添加的边的一个endpoint