KotlinにはforEach
やrepeat
のような非常に素晴らしい反復関数がありますが、break
およびcontinue
演算子をそれらと連携させることはできません(ローカルおよび非ローカルの両方) ):
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の 古いドキュメント-リンクが壊れています によると、アノテーションを使用することが可能です。ただし、まだ実装されていません。
カスタム制御構造のブレークアンドコンティニューはまだ実装されていません
この機能の issue は3年前なので、修正される予定はありません。
元の回答:(Int) -> Unit
を指定するので、コンパイラーがループで使用されていることを知らないため、それを中断することはできません。
いくつかのオプションがあります:
通常のforループを使用します:
for (index in 0..times - 1) {
// your code here
}
ループがメソッドの最後のコードである場合return
を使用してメソッドから抜けることができます(unit
メソッドでない場合はreturn value
)。
メソッドを使用する
継続のためにBoolean
を返すカスタム繰り返しメソッドを作成します。
public inline fun repeatUntil(times: Int, body: (Int) -> Boolean) {
for (index in 0..times - 1) {
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)
}
}
これは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)
}
}
Kotlin Playground で試してください。
ラムダ式からの戻り を使用できます。これは、使用状況に応じてcontinue
またはbreak
を模倣します。
これは関連する質問でカバーされています: Kotlin内の機能ループで「ブレーク」または「継続」を行う方法
Kotlinのドキュメントによると のように、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")
}
andLocal Return(forEach =継続を通過するのを止めない)
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")
}
ドキュメントをチェックしてください、本当に良いです:)
ブレークは以下を使用して達成できます。
//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 https://kotlinlang.org/docs/reference/returns.html#return-at-labels
continue
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 until
を使用する必要があります
for (index in 0 until list.size) {
val item = listOfItems[index] // you can use data item now
if () {
// your code
break
}
// your code
}