如何打破 Kotlin `repeat` 循环?

Gra*_*ier 10 kotlin

如何跳出 Kotlinrepeat循环?
(我看到很多关于 的答案forEach,但我想看到一个repeat具体的答案。)

  • 您不能使用 bare return,因为它将从包含 的内容中返回repeat
  • 您不能使用break,因为:
    • 如果repeat位于循环内,您将打破循环
    • 如果repeat不在循环中,你会得到'break' and 'continue' are only allowed inside a loop

这些不起作用(它们在功能上是相同的):

    repeat(5) { idx ->
        println(">> $idx")
        if(idx >= 2)
            return@repeat   // use implicit label
    }

    repeat(5) @foo{ idx ->
        println(">> $idx")
        if(idx >= 2)
            return@foo      // use explicit label
    }

Run Code Online (Sandbox Code Playgroud)

在这两种情况下,您都会得到:

>> 0
>> 1
>> 2
>> 3
>> 4
Run Code Online (Sandbox Code Playgroud)

return@这两个块中的实际上的作用就像一个,如果您在if 块后面continue添加一个,您可以自己看到它。)println

那么我怎样才能摆脱困境呢repeat

Gra*_*ier 12

事实证明repeat( 以及forEach) 实际上并不是循环。它们是高阶函数,也就是说,它们是以函数为参数的函数。

(我觉得这令人沮丧:它们看起来和行为都像循环,并且在 Kotlin 文档中占据显着位置。为什么不直接将它们提升为语言中的正确循环呢?)

为了打破循环repeat,这是我能想到的最佳答案:

    run repeatBlock@ { // need to make a label outside of the repeat!
        repeat(20) { idx ->
            println(">> $idx")
            if(idx >= 2)
                return@repeatBlock
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是这样做的结果:

>> 0
>> 1
>> 2
Run Code Online (Sandbox Code Playgroud)

我希望我可以在不引入新的缩进级别的情况下做到这一点,但我认为这是不可能的。

  • 拥有看起来像新语言语法的函数不仅仅是“repeat()”和“forEach()”——主要优点是_你可以编写自己的_! (3认同)

Ada*_*hip 7

这似乎是对该repeat功能的滥用。我的理解是,如果你写repeat,你就打算让它重复那么多次。任何更少都是令人惊讶的。

对于您的示例,我将使用for循环:

for (idx in 0 until 20) {
    println(">> $idx")
    if (idx >= 2)
        break
}
Run Code Online (Sandbox Code Playgroud)

我认为使用正确的工具比试图强迫错误的工具(repeat)做你想做的事情要好。


repeat其本身是作为循环实现的for

for (index in 0 until times) {
    action(index)
}
Run Code Online (Sandbox Code Playgroud)

尝试将它用于更多用途,您也可以编写自己的版本,而不是在其之上包装额外的行为。