#android #rx-java #kotlin
#Android #rx-java #котлин
Вопрос:
Я использую RxJava в одном из своих проектов, я преобразовал один из своих классов в Kotlin с помощью плагина Android Studio, и в одном из map flatMap
lambda (Func1 в Java) промежуточные возвраты выглядят следующим образом @Func1
.
Я понятия не имею, что это значит.
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)
})
Ответ №1:
В Kotlin return@label
синтаксис используется для указания, из какой функции из нескольких вложенных возвращается этот оператор.
Он работает с литералами функций (лямбды) и локальными функциями. Немаркированные return
операторы возвращаются из ближайшего (то есть самого внутреннего) окружения fun
(игнорируя лямбды). Рассмотрим эту функцию:
fun foo(ints: List<Int>) {
ints.forEach {
if (it == 0) return
print(it)
}
}
Здесь return
завершится выполнение foo
, а не только лямбда-выражения.
Но если вы хотите выполнить возврат из любой другой функции (лямбда или внешней fun
), вы должны указать ее в качестве метки в return
инструкции:
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"]
Нелокальный возврат (т. Е. возврат из внешних функций) из лямбда-выражения поддерживается только для локальных и встроенных функций, потому что, если лямбда-выражение не встроено (или функция помещена внутри объекта), не гарантируется, что оно будет вызвано только внутри заключающей функции (например, его можно сохранить в переменной и вызвать позже), и нелокальный возврат в этом случае не имел бы смысла.
Существует также аналогичный синтаксис для qualified this
, который используется для ссылки на приемники внешних областей: this@outer
.
Комментарии:
1. Спасибо! Было бы неплохо, если бы официальные документы Kotlin описали это немного подробнее с примерами, как вы сделали здесь.
Ответ №2:
return@name
определяет, для какой инструкции closure return
следует применять.
В Kotlin вы можете вызвать return из вложенного замыкания, чтобы завершить внешнее замыкание. В Java это невозможно.
Обычно это значение можно опустить @name
.
В вашем примере вы не можете пропустить это, потому что Func1
используется внутри другой функции.
Комментарии:
1. Если код написан внутри тела функции,
@Func1
его нельзя опустить.2. Не могли бы вы подробнее рассказать о том, при каких условиях
@Func1
можно опустить? Я попытался использовать выражениеsomething.flatMap(...)
в объявлении верхнего уровня, но я получил ошибку »return
здесь не разрешено».3. Спасибо! Оба ответа @hotkey и mklimek верны, ответ hotkey просто немного более сложный, я поддерживаю оба и проверяю горячие клавиши 🙂
4. Возможно ли использовать это для
when
(эквивалент коммутатора на Kotlin)? Много раз я хочу разорвать его, когда отступ слишком велик…