Kotlin ループ制御

For ループ

for ループは、イテレータ(iterator)を提供する任意のオブジェクトを走査できます。構文は次のとおりです:

for (item in collection) print(item)

ループ本体はコードブロックにすることができます:

for (item: Int in ints) {
    // ……
}

上記のように、for はイテレータを提供する任意のオブジェクトをループで走査できます。

インデックスを使って配列やリストを走査したい場合は、次のようにします:

for (i in array.indices) {
    print(array[i])
}

この「区間を走査する」方法は、最適化された実装にコンパイルされ、余分なオブジェクトは作成されないことに注意してください。

または、ライブラリ関数の withIndex を使用することもできます:

for ((index, value) in array.withIndex()) {
    println("the element at $index is $value")
}

例

コレクションを反復処理する:

fun main(args: Array<String>) {
    val items = listOf("apple", "banana", "kiwi")
    for (item in items) {
        println(item)
    }

    for (index in items.indices) {
        println("item at $index is ${items[index]}")
    }
}

出力結果:

apple
banana
kiwi
item at 0 is apple
item at 1 is banana
item at 2 is kiwi

while と do...while ループ

while は最も基本的なループで、その構造は次のとおりです:

while( 布尔表达式 ) {
  //循环内容
}

do…while ループ while 文の場合、条件を満たさなければループに入ることができません。しかし、条件を満たさなくても少なくとも1回は実行したい場合もあります。

do…while ループは while ループと似ていますが、do…while ループは少なくとも1回は実行される点が異なります。

do {
       //代码语句
}while(布尔表达式);

例

fun main(args: Array<String>) {
    println("----while 使用-----")
    var x = 5
    while (x > 0) {
        println( x--)
    }
    println("----do...while 使用-----")
    var y = 5
    do {
        println(y--)
    } while(y>0)
}

出力結果:

----while 使用-----
5
4
3
2
1
----do...while 使用-----
5
4
3
2
1

リターンとジャンプ

Kotlin には3つの構造化ジャンプ式があります:

  • return・デフォルトでは、それを最も直接的に囲む関数または匿名関数からリターンします。
  • break・それを最も直接的に囲むループを終了します。
  • continue・それを最も直接的に囲むループの次の反復を続行します。

ループ内で、Kotlin は従来の break および continue 演算子をサポートしています。

fun main(args: Array<String>) {
    for (i in 1..10) {
        if (i==3) continue  // i 为 3 时跳过当前循环,继续下一次循环
        println(i)
        if (i>5) break   // i 为 6 时 跳出循环
    }
}

出力結果:

1
2
4
5
6

Break と Continue ラベル

Kotlin では、任意の式にラベル(label)を付けることができます。ラベルの形式は、識別子の後に @ 記号を続けたものです。例:abc@、fooBar@ は有効なラベルです。式にラベルを付けるには、式の前にラベルを置くだけです。

loop@ for (i in 1..100) {
    // ……
}

では、ラベルを使って break または continue を制限できます:

loop@ for (i in 1..100) {
    for (j in 1..100) {
        if (……) break@loop
    }
}

ラベルで制限された break は、そのラベルで指定されたループの直後の実行ポイントにジャンプします。continue は、ラベルで指定されたループの次の反復を続行します。

ラベルでのリターン

Kotlin には関数リテラル、ローカル関数、オブジェクト式があります。したがって、Kotlin の関数はネストできます。ラベルで制限された return は、外側の関数から戻ることを可能にします。最も重要な用途の1つは、ラムダ式から戻ることです。次のように書いたときを思い出してください:

fun foo() {
    ints.forEach {
        if (it == 0) return
        print(it)
    }
}

この return 式は、それを最も直接的に囲む関数、つまり foo から戻ります。(注意:この非ローカルな return は、インライン関数に渡されたラムダ式でのみサポートされます。)ラムダ式から戻る必要がある場合は、ラムダ式にラベルを付けて、そのラベルで return を制限する必要があります。

fun foo() {
    ints.forEach lit@ {
        if (it == 0) return@lit
        print(it)
    }
}

これで、ラムダ式からのみ戻ります。通常、暗黙のラベルを使用する方が便利です。そのラベルは、そのラムダを受け取る関数と同じ名前です。

fun foo() {
    ints.forEach {
        if (it == 0) return@forEach
        print(it)
    }
}

または、ラムダ式の代わりに無名関数を使用することもできます。無名関数内の return 文は、その無名関数自身から戻ります。

fun foo() {
    ints.forEach(fun(value: Int) {
        if (value == 0) return
        print(value)
    })
}

値を返す場合、パーサーはラベルで制限された return を優先します。つまり

return@a 1

これは「ラベル @a から 1 を返す」という意味であり、「ラベルが付けられた式 (@a 1) を返す」という意味ではありません。

その他の拡張