Funkcje inline w Kotlinie są definiowane za pomocą słowa kluczowego inline i instruują kompilator, aby "wstawiał" ciało funkcji bezpośrednio w miejsca jej wywołania. Zmniejsza to koszty wywołania funkcji, szczególnie gdy używane są lambdy lub krótkie funkcje, i eliminuje alokację dodatkowych obiektów do przechwytywania zamknięć.
Przykład:
def inline fun synchronized(lock: Any, block: () -> Unit) { kotlin.synchronized(lock) { block() } }
Główne zalety:
Wady:
Rekomendacja: Używaj inline, gdy chcesz zwiększyć wydajność w krytycznych miejscach kodu, gdzie intensywnie używane są lambdy.
Jakie ograniczenie istnieje dla funkcji inline przy pracy z typami argumentów reified?
Nieprawidłowa odpowiedź często: "Typy realizowane są zawsze dostępne wewnątrz każdej funkcji inline."
Prawidłowa odpowiedź: Tylko funkcje inline mogą używać modyfikatora reified w definicji generyków, co pozwala na dostęp do typu w czasie wykonywania:
inline fun <reified T> getTypeName() = T::class.java.name
W zwykłej funkcji generycznej dostęp do typu T w czasie wykonywania nie będzie możliwy.
Historia
Źle używane inline doprowadziło do zwiększenia rozmiaru APK: W zespole projektu Android programiści oznaczyli dziesiątki funkcji pomocniczych jako inline, w tym funkcje z dużymi, skomplikowanymi ciałami. Efekt — rozmiar APK wzrósł prawie o 2 MB z powodu duplikacji funkcji w każdym miejscu wywołania.
Historia
Błąd z lambdami i dostępem do prywatnych zmiennych: Używano funkcji inline z lambdą, w której odwoływano się do prywatnych członków klasy. Po przeniesieniu funkcji do zewnętrznego modułu kod przestał się kompilować (naruszone uprawnienia), co odkryto dopiero na CI.
Historia
Użycie reified poza funkcją inline: Jeden z programistów próbował zadeklarować funkcję z parametrem generycznym reified bez modyfikatora inline. Kod się nie kompilował, co spowodowało długie dochodzenie nowego członka zespołu, dlaczego "T::class" nie jest dostępne poza funkcjami inline.