Kotlin Schleifensteuerung

For-Schleife

Die for-Schleife kann über jedes Objekt iterieren, das einen Iterator bereitstellt. Die Syntax lautet wie folgt:

for (item in collection) print(item)

Der Schleifenrumpf kann ein Codeblock sein:

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

Wie oben erwähnt, kann for über jedes Objekt iterieren, das einen Iterator bereitstellt.

Wenn Sie ein Array oder eine Liste per Index durchlaufen möchten, können Sie dies wie folgt tun:

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

Beachten Sie, dass diese "Iteration über einen Bereich" zu einer optimierten Implementierung kompiliert wird, ohne zusätzliche Objekte zu erzeugen.

Alternativ können Sie die Bibliotheksfunktion withIndex verwenden:

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

Beispiel

Iteration über eine Sammlung:

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

Ausgabeergebnis:

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

while- und do...while-Schleifen

while ist die grundlegendste Schleife; ihre Struktur ist:

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

do...while-Schleife Bei der while-Anweisung kann die Schleife nicht betreten werden, wenn die Bedingung nicht erfüllt ist. Manchmal müssen wir jedoch mindestens einmal ausführen, selbst wenn die Bedingung nicht erfüllt ist.

Die do...while-Schleife ähnelt der while-Schleife, außer dass die do...while-Schleife mindestens einmal ausgeführt wird.

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

Beispiel

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

Ausgabeergebnis:

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

Rückgaben und Sprünge

Kotlin hat drei strukturierte Sprungausdrücke:

  • returnStandardmäßig wird aus der Funktion oder anonymen Funktion zurückgegeben, die sie am unmittelbarsten umgibt.
  • breakBeendet die Schleife, die sie am unmittelbarsten umgibt.
  • continueSetzt mit der nächsten Iteration der Schleife fort, die sie am unmittelbarsten umgibt.

In Schleifen unterstützt Kotlin die traditionellen Operatoren break und 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 时 跳出循环
    }
}

Ausgabeergebnis:

1
2
4
5
6

break- und continue-Labels

In Kotlin kann jeder Ausdruck mit einem Label markiert werden. Das Format eines Labels ist ein Bezeichner, gefolgt vom @-Symbol, zum Beispiel: abc@ und fooBar@ sind gültige Labels. Um einen Ausdruck zu markieren, setzen wir einfach das Label davor.

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

Jetzt können wir Labels verwenden, um break oder continue zu qualifizieren:

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

Ein mit einem Label versehenes break springt zu dem Ausführungspunkt unmittelbar nach der durch das Label angegebenen Schleife. Ein mit einem Label versehenes continue fährt mit der nächsten Iteration der durch das Label angegebenen Schleife fort.

return an Labels

Kotlin hat Funktionsliterale, lokale Funktionen und Objektausdrücke. Daher können Kotlin-Funktionen verschachtelt werden. Ein mit Label versehenes return ermöglicht es uns, aus einer äußeren Funktion zurückzukehren. Eine der wichtigsten Verwendungen ist die Rückkehr aus einem Lambda-Ausdruck. Erinnern Sie sich, wenn wir schreiben:

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

Dieser return-Ausdruck kehrt aus der Funktion zurück, die ihn direkt umgibt, d. h. foo. (Beachten Sie, dass diese Art von nicht-lokalem return nur für Lambda-Ausdrücke unterstützt wird, die an Inline-Funktionen übergeben werden.) Wenn wir aus einem Lambda-Ausdruck zurückkehren müssen, müssen wir ihn mit einem Label versehen und dieses Label verwenden, um das return zu qualifizieren.

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

Jetzt wird nur aus dem Lambda-Ausdruck zurückgekehrt. Normalerweise ist es bequemer, ein implizites Label zu verwenden. Dieses Label hat denselben Namen wie die Funktion, die das Lambda entgegennimmt.

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

Alternativ können wir den Lambda-Ausdruck durch eine anonyme Funktion ersetzen. Eine return-Anweisung innerhalb einer anonymen Funktion kehrt aus der anonymen Funktion selbst zurück.

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

Wenn ein Wert zurückgegeben werden soll, bevorzugt der Parser das label-qualifizierte return, d. h.,

return@a 1

Das bedeutet "return 1 vom Label @a", nicht "einen mit Label annotierten Ausdruck zurückgeben (@a 1)".

Andere Erweiterungen