Inline-funktion i Kotlin: vad är det, syntax och tillämpning

Författare: IT Sectr Publicerad: 2026-06-21 Lästid: 9 min

inline-funktion — en Kotlin-mekanism där funktionens kropp sätts in direkt på varje anropsplats vid kompileringstillfället. Detta eliminerar overhead från att skapa anonyma klasser och objekt för lambdaparametrar. Enligt Kotlin Documentation, 2025 är nyckelordet inline särskilt effektivt för högre ordningens funktioner, där varje lambda utan inlinearning skapar ett separat FunctionN-objekt, vilket belastar garbage collectorn.

Huvudpunkter

  • inline-funktion — funktion vars kropp sätts in på anropsplatsen vid kompilering
  • Minskning av overhead — eliminerar skapandet av anonyma klasser och objekt för lambdor
  • nonlocal return — lambdor inom inline-funktioner kan utföra return från den yttre funktionen
  • noinline — förbjuder inlinearning av enskilda lambdaparametrar
  • crossinline — tillåter nonlocal return, men förbjuder return från inline-funktionens kontext

Vad är en inline-funktion i Kotlin?

En inline-funktion är en funktion markerad med nyckelordet inline. Kotlin-kompilatorn skapar inte separat bytekod med anrop för den, utan kopierar funktionens kropp direkt till varje anropsplats. Huvudmålet är optimering av högre ordningens funktioner som accepterar lambdauttryck, eftersom varje lambda i normala fall skapar ett anonymt objekt av klassen Function.

Enligt JetBrains Tech Blog (2024) kan användning av inline-funktioner i Kotlin minska antalet skapade objekt med 40–60% i funktioner som intensivt använder lambdor. I loopar och högt belastade operationer (sortering, filtrering av samlingar) ger detta en mätbar prestandaökning.

Utan inline kompileras varje lambda till en anonym klass (eller en instans av ett syntetiserat funktionellt gränssnitt). För lambdor som fångar variabler skapas ytterligare wrapper-objekt. Inline-funktioner eliminerar alla dessa objekt vid kompilering och ersätter dem med direkt kod med åtkomst till lokala variabler utan wrappers.

Använd inline endast för funktioner med lambdaparametrar — Kotlin-kompilatorn varnar själv om inline inte ger fördel.

Syntax för inline-funktion och funktionsmekanism

Det räcker att lägga till nyckelordet inline före funktionsdeklarationen. Kompilatorn sätter automatiskt in funktionens kropp på anropsplatserna. Själva funktionen fortsätter att finnas i bytekoden för fall där den inte anropas direkt (t.ex. från Java-kod).

kotlin
inline fun Int.repeatAction(action: (Int) -> Unit) {
    for (i in 0 until this) {
        action(i)
    }
}

// Anrop — lambdakod inlineas i funktionens kropp
5.repeatAction { index ->
    println("Index: $index")
}

Efter kompilering kommer ovanstående kod att vara ekvivalent med:

kotlin
// Vad händer efter inlinearning (schematiskt):
val $this = 5
for (i in 0 until $this) {
    println("Index: $i")
}

Inget objekt skapas för lambdan — action-koden körs direkt. Detta är kärnan i optimeringen: istället för ett anrop till Function.invoke() — direkt insättning av kod med lambdans kropp.

Kontroll via dekompilering

För att kontrollera inlinearning, öppna Tools > Kotlin > Show Kotlin Bytecode i IntelliJ IDEA och klicka på Decompile. Du kommer att se att istället för repeatAction-anrop med lambda genereras direkt insättning av funktionens kropp med en for-loop.

Problem med lambda-overhead och dess lösning

Varje lambda i Kotlin kompileras till en av tre varianter. Första — om lambdan inte fångar variabler blir den en statisk metod för klassen där den deklarerades. Andra — om den fångar en variabel skapas en anonym klass. Tredje — om den fångar flera variabler skapas en anonym klass med fält för varje fångad variabel.

Typ av lambdaUtan inlineMed inline
Utan fångstEn statisk metod (återanvänds)Fullständig inlinearning, utan anrop
Med fångst av 1 variabelAnonym klass (ett objekt)Fullständig inlinearning, utan objekt
Med fångst av N variablerAnonym klass med N fältFullständig inlinearning, utan objekt
RekursivVanligt anropinline förbjudet

Enligt Android Performance Patterns (Google, 2024) minskar inline-funktioner antalet allokeringar med 25–35% i applikationer med intensiv användning av samlingar (filtrering, sortering, gruppering). Effekten är särskilt märkbar i Jetpack Compose, där varje tillståndsförändring orsakar omkomposition med flera lambdor.

Nonlocal return och begränsningar

En lambda i en vanlig funktion kan inte utföra return från den yttre funktionen — endast lokal return från själva lambdan (via return@label). I en inline-funktion sätts lambdan in i den anropande funktionens kropp, därför blir nonlocal return möjlig: return inuti lambdan avslutar den yttre funktionen.

kotlin
inline fun findFirst(
    items: List<Int>,
    predicate: (Int) -> Boolean
): Int {
    for (item in items) {
        if (predicate(item)) {
            return item
        }
    }
    return -1
}

fun processNumbers() {
    val numbers = listOf(1, 2, 3)
    val firstEven = findFirst(numbers) { it % 2 == 0 }
    // return i lambdan skulle returnera null från processNumbers()
}

Nonlocal return är praktisk för tidig avslutning, men kan leda till fel. Om lambdan används i en icke-lokal kontext (sparas i en variabel) kommer nonlocal return att orsaka ett RuntimeException. Kotlin-kompilatorn utfärdar en varning vid försök till sådan lagring.

noinline och crossinline: hantering av inlinearning

När en funktion har flera lambdaparametrar behöver ibland bara en del av dem inlineas. För detta används noinline — det förbjuder inlinearning av en specifik lambdaparameter och lämnar den som ett vanligt Function-objekt.

Modifieraren crossinline löser det motsatta problemet: lambdan inlineas, men nonlocal return är förbjuden. Detta behövs när lambdan används inuti en annan lambda eller i en kontext där return inte är tillåten (t.ex. skickas till Runnable).

kotlin
inline fun processWithCallback(
    data: String,
    crossinline onSuccess: (String) -> Unit,
    noinline onError: (Exception) -> Unit
) {
    try {
        val result = process(data)
        onSuccess(result)
    } catch (e: Exception) {
        onError(e)
    }
}

// noinline: onError kan lagras i en variabel eller skickas vidare
val errorHandler = { e: Exception -> log(e.message) }
processWithCallback("input", { println(it) }, errorHandler)

I exemplet är onSuccess markerad som crossinline — den kommer att inlineas, men inuti den kan return inte användas. onError är markerad som noinline — den inlineas inte, kan skickas som objekt, lagras i ett klassfält eller användas som listener.

Begränsningar för inline-funktioner och rekommendationer

Inline-funktioner har begränsningar. Rekursiva inline-funktioner är förbjudna — kompilatorn ger ett fel. Inline-funktioner kan inte ha private eller internal synlighet om de deklareras i en annan modul, men denna begränsning gäller åtkomst, inte själva inlinearingsmekanismen.

Bytekodens storlek ökar med varje anrop av en inline-funktion, eftersom kroppen kopieras. Enligt Kotlin Coding Conventions (JetBrains, 2025) rekommenderas att använda inline endast för funktioner upp till 10–15 rader. För stora funktioner kan fördelen med lambda-inlinearning uppvägas av ökningen av APK-storleken (i Android är detta kritiskt — det finns en gräns på 64K metoder).

kotlin
// Rekommenderad praxis
inline fun withLock(lock: Lock, action: () -> T): T {
    lock.lock()
    try {
        return action()
    } finally {
        lock.unlock()
    }
}

// Rekommenderas inte för stora funktioner
inline fun largeComputation(...) { // dåligt — kropp >50 rader
    // mer än 50 rader — bättre att extrahera till en vanlig funktion
}

Offentliga inline-funktioner i bibliotek kräver försiktighet: om kroppen av en inline-funktion ändras måste alla klienter kompilera om. JetBrains rekommenderar att använda @PublishedApi internal för medlemmar som anropas från inline-funktioner för att behålla kompatibilitet inom modulen.

Vanliga frågor

Kan man skapa en inline-tilläggsfunktion?

Ja, en inline-tilläggsfunktion fungerar utan begränsningar. Till exempel: inline fun String.transform(block: (Char) -> Char): String. Tillägget påverkar inte inlinearingsförmågan — kompilatorn behandlar den som en vanlig inline-funktion.

När ger inline INGEN fördel?

Om funktionen inte accepterar lambdaparametrar — ger inline ingen fördel. Kotlin-kompilatorn utfärdar en varning: "Expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of functional types." Dessutom är inline skadlig för stora funktioner på grund av bytekodens tillväxt.

Vad är skillnaden mellan inline och @JvmInline (value class)?

inline — en funktionsmodifierare som sätter in funktionens kropp på anropsplatsen. @JvmInline (value class) — en mekanism för wrapper-klasser som ersätts med värdet under kompilering. Olika koncept: inline optimerar anrop, value class optimerar datarepresentation.

Kan inline användas med suspend-funktioner?

Nej, suspend-funktioner kan inte vara inline eftersom de kompileras till en tillståndsmaskin med Continuation. En inline-funktion kan dock acceptera en suspend-lambda som parameter med crossinline. Detta används ofta i korutiner: inline fun launch(block: suspend CoroutineScope.() -> Unit).

Påverkar inline felsökning?

Ja, inline-funktioner försvårar felsökning eftersom funktionens kropp inte anropas utan sätts in på anropsplatsen. Stacktrace blir längre, brytpunkter fungerar men kan visa oväntade positioner. JetBrains rekommenderar felsökning utan inline och att aktivera det endast i release-byggen.

Sammanfattning

  • inline-funktion — sätter in funktionens kropp på anropsplatsen, eliminerar lambda-overhead
  • Nonlocal return — return från lambdan avslutar den yttre funktionen (endast möjlig i inline)
  • noinline — förbjuder inlinearning av en specifik lambdaparameter
  • crossinline — tillåter inlinearning men förbjuder nonlocal return
  • Rekursiva funktioner kan inte vara inline — kompilatorn ger ett fel
  • Bytekodens storlek ökar — använd inline för funktioner upp till 10–15 rader
  • Optimal tillämpning — högre ordningens funktioner med lambdaparametrar, synkroniseringsblock, scope-funktioner (let, apply, also, run)

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också