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