Contrôle des boucles en Kotlin

Boucle For

La boucle for peut parcourir tout objet qui fournit un itérateur. La syntaxe est la suivante :

for (item in collection) print(item)

Le corps de la boucle peut être un bloc de code :

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

Comme mentionné ci-dessus, for peut parcourir tout objet qui fournit un itérateur.

Si vous souhaitez parcourir un tableau ou une liste par indice, vous pouvez faire ceci :

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

Notez que cette « itération sur un intervalle » est compilée en une implémentation optimisée sans créer d'objets supplémentaires.

Vous pouvez également utiliser la fonction de bibliothèque withIndex :

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

Exemple

Itération sur une collection :

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

Résultat de sortie :

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

Boucles while et do...while

while est la boucle la plus élémentaire ; sa structure est :

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

Boucle do...while Pour l'instruction while, si la condition n'est pas remplie, il n'est pas possible d'entrer dans la boucle. Mais parfois, nous devons exécuter au moins une fois même si la condition n'est pas remplie.

La boucle do...while est similaire à la boucle while, sauf que la boucle do...while est exécutée au moins une fois.

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

Exemple

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

Résultat de sortie :

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

Retours et sauts

Kotlin dispose de trois expressions de saut structurées :

  • returnPar défaut, effectue un retour depuis la fonction ou la fonction anonyme qui l'entoure le plus directement.
  • breakTermine la boucle qui l'entoure le plus directement.
  • continuePasse à l'itération suivante de la boucle qui l'entoure le plus directement.

Dans les boucles, Kotlin prend en charge les opérateurs traditionnels break et 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 时 跳出循环
    }
}

Résultat de sortie :

1
2
4
5
6

Étiquettes break et continue

En Kotlin, toute expression peut être marquée par une étiquette. Le format d'une étiquette est un identifiant suivi du symbole @, par exemple : abc@ et fooBar@ sont des étiquettes valides. Pour étiqueter une expression, il suffit de placer l'étiquette devant celle-ci.

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

Maintenant, nous pouvons utiliser des étiquettes pour qualifier break ou continue :

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

Un break étiqueté saute au point d'exécution juste après la boucle spécifiée par l'étiquette. Un continue étiqueté passe à l'itération suivante de la boucle spécifiée par l'étiquette.

Retour sur les étiquettes

Kotlin dispose de littéraux de fonction, de fonctions locales et d'expressions d'objet. Par conséquent, les fonctions Kotlin peuvent être imbriquées. Un retour étiqueté nous permet de revenir d'une fonction externe. L'un des usages les plus importants est le retour depuis une expression lambda. Rappelons que lorsque nous écrivons :

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

Cette expression de retour renvoie depuis la fonction qui l'entoure directement, c'est-à-dire foo. (Notez que ce type de retour non local n'est pris en charge que pour les expressions lambda transmises à des fonctions inline.) Si nous devons revenir depuis une expression lambda, nous devons l'étiqueter et utiliser cette étiquette pour qualifier le retour.

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

Maintenant, il ne reviendra que depuis l'expression lambda. Habituellement, il est plus pratique d'utiliser une étiquette implicite. Cette étiquette porte le même nom que la fonction qui accepte la lambda.

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

Alternativement, nous pouvons remplacer l'expression lambda par une fonction anonyme. Une instruction return à l'intérieur d'une fonction anonyme renverra depuis la fonction anonyme elle-même.

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

Lorsqu'une valeur doit être renvoyée, l'analyseur préfère le retour qualifié par étiquette, c'est-à-dire

return@a 1

Cela signifie « renvoyer 1 depuis l'étiquette @a », et non « renvoyer une expression annotée par une étiquette (@a 1) ».

Autres extensions