81 votes

Kotlin : Que signifie "return@" ?

J'utilise RxJava dans l'un de mes projets, j'ai converti l'une de mes classes en Kotlin en utilisant le plugin Android Studio et dans l'une des map flatMap lambda (Func1 en java), les retours intermédiaires ressemblent à ce qui suit @Func1 .

Je n'ai aucune idée de ce que cela signifie.

something.flatMap(Func1<ArticleCriteria, Observable<Pair<String, String>>> {
    val isTemporaryClone = it.isATemporaryClone
    val isTheOriginalToken = it.tokenIsOriginalHere

    if (isTemporaryClone) {
        if (!isTheOriginalToken) {
            return@Func1 paramsError("Token is always original for temp articles")
        }

        return@Func1 mJobRunner.doNotRun(DeleteArticleJob.TAG)
                            .doOnNext(deletePersonalActionById(articleId))
    }

    runArticleJobAsync(DeleteArticleJob.TAG, it)
})

118voto

hotkey Points 119

En Kotlin, le return@label syntaxe est utilisé pour spécifier quelle fonction, parmi plusieurs fonctions imbriquées, cette instruction retourne.

Il fonctionne avec les littéraux de fonction (lambdas) et les fonctions locales. Non étiqueté return retournent à partir de l'instruction la plus proche (c.-à-d. la plus interne) de l'entourage. fun (en ignorant les lambdas). Considérons cette fonction :

fun foo(ints: List<Int>) {
    ints.forEach {
        if (it == 0) return
        print(it)
    }
}

Ici, return terminera l'exécution de foo et pas seulement le lambda.

Mais si vous voulez retourner de n'importe quelle autre fonction (une lambda ou une fonction externe fun ), vous devez le spécifier en tant qu'étiquette à l'endroit suivant return déclaration :

fun foo(ints: List<Int>) {
    ints.forEach {
        if (it == 0) return@forEach // implicit label for lambda passed to forEach
        print(it)
    }
}

fun foo(ints: List<Int>): List<String> {
    val result = ints.map f@{
        if (it == 0) return@f "zero" // return at named label
        if (it == -1) return emptyList() // return at foo
        "number $it" // expression returned from lambda
    }
    return result
}

foo(listOf(1, -1, 1)) // []
foo(listOf(1, 0, 1)) // ["number 1", "zero", "number 1"]

Retour non-local (c'est-à-dire le retour des fonctions externes) à partir d'un lambda n'est supporté que pour les fonctions local et en ligne car si une lambda n'est pas inlined (ou si une fonction est placée à l'intérieur d'un objet), il n'est pas garanti qu'elle soit appelée uniquement à l'intérieur de la fonction englobante (par exemple, elle peut être stockée dans une variable et appelée plus tard), et le retour non-local n'aurait aucun sens dans ce cas.


Il existe également une syntaxe similaire pour qualifié this qui est utilisé pour référencer les récepteurs des portées extérieures : this@outer .

1 votes

Merci ! Il aurait été intéressant que la documentation officielle de Kotlin couvre ce sujet de manière un peu plus détaillée avec des exemples, comme vous l'avez fait ici.

11voto

mate Points 155

return@name déterminés pour lesquels la fermeture return doit être appliquée.

En Kotlin, vous pouvez appeler le retour d'une fermeture imbriquée pour terminer la fermeture extérieure. En Java, ce n'est pas possible.

Habituellement, vous pouvez omettre @name .

Dans votre exemple, vous ne pouvez pas l'omettre car Func1 est utilisé à l'intérieur d'une autre fonction.

1 votes

Si le code est écrit à l'intérieur d'un corps de fonction, @Func1 ne peut être omise.

0 votes

Pourriez-vous préciser dans quelles conditions @Func1 peut être omise ? J'ai essayé d'utiliser l'expression something.flatMap(...) dans une déclaration de haut niveau, mais j'ai obtenu le " return n'est pas autorisé ici".

0 votes

Merci ! Les deux réponses de @hotkey et mklimek sont correctes, la réponse de hotkey est juste un peu plus élaborée. Je upvote les deux et vérifie celle de hotkey :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X