Le funzioni inline in Kotlin sono definite usando la parola chiave inline e istruiscono il compilatore a "sostituire" il corpo della funzione direttamente nei punti in cui viene chiamata. Ciò riduce i costi di chiamata della funzione, specialmente quando si usano le lambda o le funzioni brevi, e elimina l'allocazione di oggetti aggiuntivi per la cattura delle chiusure.
Esempio:
def inline fun synchronized(lock: Any, block: () -> Unit) { kotlin.synchronized(lock) { block() } }
Vantaggi principali:
Svantaggi:
Raccomandazione: Utilizzare inline quando è necessario migliorare le prestazioni nelle sezioni critiche del codice in cui si utilizzano attivamente le lambda.
Quale limitazione esiste per le funzioni inline quando si lavora con tipi argomenti reified?
Risposta errata comune: "I tipi realizzati sono sempre disponibili all'interno di qualsiasi funzione inline."
Risposta corretta: Solo le funzioni inline possono utilizzare il modificatore reified nella dichiarazione dei generici, consentendo di accedere al tipo durante il runtime:
inline fun <reified T> getTypeName() = T::class.java.name
In una normale funzione generica non ci sarà accesso al tipo T durante l'esecuzione.
Storia
L'uso errato di inline ha portato a un APK gonfiato: Nel team di un progetto Android, i programmatori hanno contrassegnato decine di funzioni utilitarie come inline, includendo funzioni con corpi complessi e grandi. Risultato — la dimensione dell'APK è aumentata di quasi 2 MB a causa della duplicazione delle funzioni in tutti i punti di chiamata.
Storia
Errore con le lambda e l'accesso a variabili private: È stata utilizzata una funzione inline con una lambda, all'interno della quale si accedeva ai membri privati della classe. Dopo aver spostato la funzione in un modulo esterno, il codice ha smesso di compilare (privilegi violati), cosa scoperta solo su CI.
Storia
Uso di reified al di fuori di una funzione inline: Uno degli sviluppatori ha cercato di dichiarare una funzione con un parametro generico reified senza il modificatore inline. Il codice non si compilava, causando una lunga indagine da parte di un nuovo assunto sul perché "T::class" non fosse accessibile al di fuori delle funzioni inline.