Inline-functies in Kotlin worden gedefinieerd met behulp van het sleutelwoord inline en instrueren de compiler om de body van de functie direct in te voegen op de plaatsen waar de functie wordt aangeroepen. Dit vermindert de kosten van functieaanroepen, vooral wanneer er gebruik wordt gemaakt van lambdas of korte functies, en voorkomt de allocatie van extra objecten voor het vastleggen van closures.
Voorbeeld:
def inline fun synchronized(lock: Any, block: () -> Unit) { kotlin.synchronized(lock) { block() } }
Hoofdvoordelen:
Nadelen:
Aanbeveling: Gebruik inline wanneer je de prestaties wilt verbeteren in kritieke delen van de code waar intensief gebruik wordt gemaakt van lambdas.
Wat is de beperking voor inline-functies bij het werken met gerealiseerde argumenttypen?
Foutenlijk antwoord vaak: "Gerealiseerde types zijn altijd beschikbaar binnen elke inline-functie."
Juiste antwoord: Alleen inline-functies kunnen de modifier reified gebruiken in de declaratie van generics, waardoor je op runtime naar het type kunt verwijzen:
inline fun <reified T> getTypeName() = T::class.java.name
In een reguliere generic-functie zal er geen toegang tot het type T tijdens uitvoering zijn.
Verhaal
Slecht gebruik van inline leidde tot een opgeblazen APK: In het Android-projectteam markeerden programmeurs tientallen utilitaire functies als inline, inclusief functies met grote complexe bodies. Het resultaat — de APK-grootte steeg met bijna 2 MB door de duplicatie van functies op alle aanroepplaatsen.
Verhaal
Fout met lambdas en toegang tot privévariabelen: Er werd een inline-functie gebruikt met een lambda, waarin werd verwezen naar privéleden van de klasse. Na het verplaatsen van de functie naar een extern module compileerde de code niet meer (privileges geschonden), wat pas op CI werd ontdekt.
Verhaal
Gebruik van reified buiten inline-functie: Een van de ontwikkelaars probeerde een functie te declareren met een reified generiek parameter zonder inline-modifier. De code compileerde niet, wat leidde tot een langdurig onderzoek door een nieuwkomer naar waarom "T::class" niet beschikbaar was buiten inline-functies.