`pause` et `continuer` dans `forEach` dans Kotlin
Kotlin a de très belles fonctions itératives, comme forEach
ou repeat
, mais je ne suis pas en mesure de faire les opérateurs break
et continue
travailler avec eux (à la fois local et non-local):
repeat(5) {
break
}
(1..5).forEach {
continue@forEach
}
le but est d'imiter les boucles habituelles avec la syntaxe fonctionnelle aussi proche que possible. C'était certainement possible dans certaines versions plus anciennes de Kotlin, mais j'ai du mal à reproduire la syntaxe.
le problème pourrait être un bug avec labels (M12), mais je pense que le premier exemple devrait fonctionner de toute façon.
il me semble que j'ai lu quelque part à propos d'une astuce/annotation spéciale, mais je n'ai pas pu trouver de référence sur le sujet. Pourrait ressembler à ce qui suit:
public inline fun repeat(times: Int, @loop body: (Int) -> Unit) {
for (index in 0..times - 1) {
body(index)
}
}
4 réponses
Modifier :
Selon le de Kotlin "vieux documents , il devrait être possible d'utiliser des annotations. Cependant, il n'est pas encore mis en œuvre.
Break et continue pour personnalisé les structures de contrôle ne sont pas mis en œuvre pourtant
le issue pour cette fonctionnalité est de 3 ans, donc je suppose qu'il ne va pas être fixé.
Réponse Originale :
Puisque vous fournissez un (Int) -> Unit
, vous ne pouvez pas le rompre, puisque le compilateur ne sait pas qu'il est utilisé dans une boucle.
vous avez peu d'options:
utiliser un régulier pour boucle:
for (index in 0..times - 1) {
// your code here
}
si la boucle est le dernier code de la méthode
vous pouvez utiliser return
pour sortir de la méthode (ou return value
si elle n'est pas unit
la méthode).
utiliser une méthode
Créer une méthode de répétition méthode qui retourne Boolean
pour continuer.
public inline fun repeatUntil(times: Int, body: (Int) -> Boolean) {
for (index in 0..times - 1) {
if (!body(index)) break
}
}
1 à 5. Le return@forEach
agit comme le mot-clé continue
en Java, ce qui signifie que dans ce cas, il exécute toujours chaque boucle mais passe à la prochaine itération si la valeur est supérieure à 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)
}
}
ce sera imprimé 1 à 10 mais saute 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)
}
}
de les Essayer à la Kotlin aire de Jeux .
vous pouvez utiliser retour de l'expression lambda qui imite un continue
ou break
selon votre usage.
C'est couvert dans la question connexe: Comment puis-je faire une "break" ou "continue" quand dans une boucle fonctionnelle à L'intérieur de Kotlin?
comme le documentation Kotlin dit , en utilisant return
est la voie à suivre. Une bonne chose à propos de kotlin est que si vous avez des fonctions imbriquées, vous pouvez utiliser des étiquettes pour écrire explicitement où votre retour est de:
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")
}
et
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")
}
Vérifiez la documentation, c'est vraiment bon :)