Inline Functions
Kotlin's inline functions are expanded (inlined) by the compiler at the call site. Using inline on higher-order functions that take lambdas reduces the overhead of object creation, and allows return statements inside lambdas to return from the enclosing function.
Syntax
// Defining an inline function
inline fun measure(block: () -> Unit) {
val start = System.currentTimeMillis()
block()
println("${System.currentTimeMillis() - start}ms")
}
// noinline — prevents a specific lambda from being inlined
inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) { ... }
// crossinline — inlines the lambda but disallows non-local returns
inline fun bar(crossinline block: () -> Unit) { ... }
// reified — retains type information at runtime through inlining
inline fun <reified T> isInstance(value: Any): Boolean = value is T
Modifier List
| Modifier | Description |
|---|---|
| inline | Expands the function body at the call site. Reduces object creation for lambda arguments. |
| noinline | Prevents a specific lambda parameter of an inline function from being inlined. Use this when you need to store the lambda in a variable. |
| crossinline | Inlines the lambda while prohibiting non-local returns (returning from the lambda to the enclosing function). |
| reified | Only available in inline functions. Allows type parameters to be accessed at runtime. |
Sample Code
// Inline function for measuring execution time
inline fun measureTime(label: String, block: () -> Unit) {
val start = System.currentTimeMillis()
block()
println("$label: ${System.currentTimeMillis() - start}ms")
}
// Using reified to access type information at runtime
inline fun <reified T> filterByType(list: List<Any>): List<T> {
return list.filterIsInstance<T>()
}
// In an inline function, a lambda can return from the enclosing function (non-local return)
inline fun findFirst(list: List<Int>, predicate: (Int) -> Boolean): Int? {
for (item in list) {
if (predicate(item)) return item // This return exits findFirst itself.
}
return null
}
fun main() {
// Using measureTime
measureTime("process") {
Thread.sleep(10)
println("Processing...")
}
// Using reified (accessing type information at runtime)
val mixed: List<Any> = listOf(1, "hello", 2.5, "world", 42, true)
val strings = filterByType<String>(mixed)
val ints = filterByType<Int>(mixed)
println("Strings: $strings") // [hello, world]
println("Integers: $ints") // [1, 42]
// Non-local return (inline allows returning from the enclosing main())
val numbers = listOf(1, 3, 5, 7, 2, 9)
val firstEven = findFirst(numbers) { it % 2 == 0 }
println("First even number: $firstEven") // 2
// Example of inline functions from the standard library
val result = listOf(1, 2, 3, 4, 5).let { list ->
list.filter { it > 2 }.sumOf { it }
}
println("Sum of values greater than 3: $result") // 12
}
Overview
Normally, Kotlin lambda expressions are compiled into objects at runtime. Using inline expands the code at the call site, eliminating the cost of creating lambda objects. This is especially effective for frequently called utility functions.
reified type parameters are only available in inline functions. In normal generics, type information is erased at runtime, but inlining preserves it, enabling the use of is T and T::class.
For the basics of lambda expressions, see Lambda Expressions. For higher-order functions, see Higher-Order Functions.
If you find any errors or copyright issues, please contact us.