2016-10-20 13 views
20

Używam RxJava w jednym z moich projektów, przekonwertowałem jedną z moich klas na Kotlin za pomocą wtyczki Android Studio i na jednej z map flatMap lambda (Func1 w java), zwraca półprodukty wygląda następująco: @Func1.Kotlin: Co oznacza "return @"?

Nie mam pojęcia, co to oznacza.

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

To jest adnotacja https://en.wikipedia.org/wiki/Java_annotation. – kichik

+0

To jest oczywiście, ale adnotacje w java są umieszczane przed metodą lub klasą nie "inline" wewnątrz bloku kodu –

+0

Możesz dodawać adnotacje więcej niż tylko metodę lub klasę w Javie - http://stackoverflow.com/questions/24229445/how-to-annotate-a-code-block-in-java – kichik

Odpowiedz

22

W Kotlin, [email protected] syntax służy do określania, która funkcja spośród kilku zagnieżdżonych, z której zwraca to polecenie.

Działa z literałami funkcji (lambdas) i funkcjami lokalnymi. Instrukcje niepolecane return powracają z najbliższego (to jest najgłębszego) kodu zawierającego fun (ignorując lambdas). Rozważmy tę funkcję:

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

Tutaj return zakończy wykonanie foo, nie tylko lambda.

Ale jeśli chcesz, aby powrócić z jakiejkolwiek innej funkcji (lambda lub zewnętrznej fun) trzeba określić go jako etykieta na return stwierdzeniem:

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 (tj. Powrót z zewnętrznych funkcji) z lambda jest obsługiwany tylko dla funkcji local i inline, ponieważ jeśli ambda nie jest wstawiona (lub funkcja jest umieszczona wewnątrz obiektu), nie można zagwarantować, że zostanie wywołana tylko wewnątrz funkcji otaczającej (np. może być przechowywany w zmiennej i wywoływany później), a zwrot nielokalny nie ma sensu w tym przypadku.


Istnieje też podobna składnia qualified this, która jest wykorzystywana do odwołania do zewnętrznych odbiorników zakresów: [email protected].

+0

Dzięki! Byłoby miło, gdyby oficjalni doktorzy Kotlin opisali to nieco bardziej szczegółowo przykładami, tak jak tutaj. –

+0

@hotkey przykład funkcji lokalnej nie jest kompilowany. Kompilator mówi, że "return" nie jest tu dozwolony "przy return @ outer 0 – Yao

5

[email protected] wyznaczników dla których powinny być stosowane zamknięcie return oświadczenie.

W aplikacji Kotlin można wywołać funkcję powrotu z zagnieżdżonego zamknięcia, aby zakończyć zewnętrzne zamknięcie. W Javie nie jest to możliwe.

Zwykle można pominąć @name.

W swoim przykładzie nie można go pominąć, ponieważ Func1 jest używany w innej funkcji.

+1

Jeśli kod jest zapisany w treści funkcji, '@ Func1' nie może zostać pominięty. – hotkey

+0

Czy mógłbyś bardziej szczegółowo opisać, w jakich warunkach można pominąć "@ Func1"? Próbowałem użyć wyrażenia 'something.flatMap (...)' w deklaracji najwyższego poziomu, ale dostałem błąd "' return' is allowed allowed here ". – hotkey

+1

@hotkey masz rację. Poprawiłem odpowiedź. – mklimek