2016-10-20 4 views
20

Я использую RxJava в одном из моих проектов, я преобразовал один из своих классов в Kotlin, используя плагин Android Studio, и на одной из карт flatMap lambda (Func1 in java), промежуточные результаты выглядят следующим образом: @Func1.Kotlin: Что означает «return @»?

Я понятия не имею, что это значит.

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

    if (isTemporaryClone) { 
     if (!isTheOriginalToken) { 
      [email protected] paramsError("Token is always original for temp articles") 
     } 

     [email protected] mJobRunner.doNotRun(DeleteArticleJob.TAG) 
          .doOnNext(deletePersonalActionById(articleId)) 
    } 

    runArticleJobAsync(DeleteArticleJob.TAG, it) 
}) 
+0

Это аннотация https://en.wikipedia.org/wiki/Java_annotation. – kichik

+0

Это конечно, но аннотации в java помещаются перед тем, как метод или класс не «встроены» внутри блока кода. –

+0

Вы можете комментировать больше, чем просто метод или класс в Java - http://stackoverflow.com/questions/24229445/how-to-annotate-a-code-block-in-java – kichik

ответ

22

В Котлине [email protected] syntax используется для указания функции из нескольких вложенных, с которой возвращается этот оператор.

Он работает с функциональными литералами (lambdas) и локальными функциями. Немаркированные операторы 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) [email protected] // implicit label for lambda passed to forEach 
     print(it) 
    } 
} 

fun foo(ints: List<Int>): List<String> { 
    val result = ints.map [email protected]{ 
     if (it == 0) [email protected] "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"] 

Non-local return (т. Е. Возврат из внешних функций) из лямбда поддерживается только для функций local и inline, потому что если al ambda не встроена (или функция помещена внутри объекта), она не может быть вызвана только внутри закрывающей функции (например, он может быть сохранен в переменной и вызван позже), и нелокальное возвращение в этом случае не имеет смысла.


Существует также аналогичный синтаксис для qualified this, который используется для ссылки на приемники внешних областей: [email protected].

+0

Спасибо! Было бы неплохо, если бы официальные документы Котлин подробно рассмотрели это с примерами, как вы это делали здесь. –

+0

@hotkey пример локальной функции не поддается компиляции. Компилятор говорит: «Возврат» здесь не разрешен »at return @ outer 0 – Yao

5

[email protected] для определенности, которые должны применяться закрытие return заявление.

В Котлин вы можете вызвать возврат из вложенного закрытия, чтобы закончить внешнее закрытие. В Java это невозможно.

Обычно вы можете опустить @name.

В вашем примере вы не можете его опустить, потому что Func1 используется внутри другой функции.

+1

Если код написан внутри тела функции, '@ Func1' не может быть опущен. – hotkey

+0

Не могли бы вы подробнее рассказать о том, какие условия '@ Func1' можно опустить? Я попытался использовать выражение 'something.flatMap (...)' в объявлении верхнего уровня, но я получил ошибку «return» здесь не допускается ». – hotkey

+1

@hotkey вы правы. Я исправил свой ответ. – mklimek

Смежные вопросы