Sobes.tech
Middle+

Do czego służy słowo kluczowe crossinline w Kotlin?

sobes.tech AI

Odpowiedź od AI

crossinline jest używany w Kotlinie do oznaczania parametrów funkcji w funkcjach inline. Pozwala to na wywołanie takiego parametru lambda wewnątrz zagnieżdżonych funkcji (takich jak obiekty anonimowych klas), które nie są inline.

Zwykłe lambdy w funkcjach inline mogą zawierać nielokalne zwroty (zwroty wychodzące z funkcji zewnętrznej). Lambda oznaczona jako crossinline nie może zawierać nielokalnych zwrotów.

Główny cel:

  • Umożliwić użycie lambdy w kontekstach, w których domyślnie inline'owa lambda (z możliwością nielokalnego zwrotu) nie może być użyta (np. obiekty anonimowe, funkcje lokalne).
  • Zapobiec nielokalnym zwrotom z lambdy, gdy jest to niepożądane lub niemożliwe ze względu na strukturę kodu (np. podczas przekazywania lambdy do innego wątku).

Przykład:

inline fun runAsyncAndFinish(crossinline block: () -> Unit) {
    // Tworzenie anonimowego obiektu Runnable
    val runnable = object : Runnable {
        override fun run() {
            block() // Użycie lambdy crossinline wewnątrz
            // tutaj block() nie może wykonać nielokalnego zwrotu z runAsyncAndFinish
        }
    }
    // Uruchomienie w osobnym wątku (przykład)
    Thread(runnable).start()
    // gdyby block nie był crossinline, block() mógłby zrobić return z runAsyncAndFinish
    // co jest niemożliwe z innego wątku niż wywołujący
}

fun testCrossinline() {
    println("Przed runAsyncAndFinish")
    runAsyncAndFinish {
        println("Wewnątrz bloku asynchronicznego")
        // return // Błąd kompilacji: nie można używać nielokalnego return z crossinline
    }
    println("Po runAsyncAndFinish")
}