1. ホーム
  2. loops

[解決済み] Kotlin の `forEach` における `break` と `continue` について

2022-04-13 16:13:59

質問

Kotlin には、次のような非常に優れた反復処理関数があります。 forEach または repeat を作成することができません。 breakcontinue 演算子が動作します (ローカルおよび非ローカルの両方)。

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の ドキュメント をシミュレートすることができます。 continue アノテーションを使用しています。

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

をシミュレートしたい場合は break を追加するだけです。 run ブロック

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) -> Unit というのも、コンパイラはそれがループの中で使われていることを知らないからです。

選択肢は少ない。

通常のforループを使用する。

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

ループがメソッド内の最後のコードである場合

を使用することができます。 return を使ってメソッドから抜け出すことができます(または return value でない場合は unit メソッド) を使用します。

メソッドを使用する

を返すカスタムリピートメソッドメソッドを作成します。 Boolean を継続させる。

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