Lambda Expressions
| Since: | Kotlin 1.0(2016) |
|---|
A lambda expression in Kotlin is an anonymous function written in the form { parameter -> body }. When there is a single parameter, you can refer to it using it. If the last argument of a function is a lambda, you can write it outside the parentheses using trailing lambda syntax.
Syntax
val lambda = { x: Int -> x * 2 }
val result = lambda(5) // 10
// Lambda with no parameters
val greet = { println("Hello!") }
// When there is one parameter, you can use it to refer to it
val double: (Int) -> Int = { it * 2 }
// Trailing lambda (when the last argument is a lambda, you can write it outside the parentheses)
listOf(1, 2, 3).map { it * 2 }
listOf(1, 2, 3).filter { it > 1 }
// Multi-line lambda (the last expression becomes the return value)
val process = { x: Int ->
val doubled = x * 2
doubled + 1 // This expression is the return value
}
Syntax Overview
| Syntax | Description |
|---|---|
| { param: Type -> body } | The basic form of a lambda expression. |
| it | The default name used to refer to the parameter in a single-parameter lambda. |
| Trailing lambda | When the last argument is a lambda, you can write { } outside the parentheses. |
| _ (underscore) | Unused parameters can be omitted with _ (Kotlin 1.1 and later). |
| return@label | Attaches a label to a return inside a lambda to distinguish it from returning from the outer function. |
Sample Code
sample_lambda_expression.kt
fun main() {
// Basic lambda expression
val add = { a: Int, b: Int -> a + b }
println(add(3, 5)) // 8
// Shorthand using it
val doubled = listOf(1, 2, 3, 4, 5).map { it * 2 }
println(doubled) // [2, 4, 6, 8, 10]
// Trailing lambda
val evens = listOf(1, 2, 3, 4, 5, 6).filter { it % 2 == 0 }
println(evens) // [2, 4, 6]
// Lambda with multiple parameters
val pairs = listOf("a" to 1, "b" to 2, "c" to 3)
pairs.forEach { (key, value) -> // Destructure the lambda parameters with a destructuring declaration
println("$key: $value")
}
// Omit unused parameters with _
pairs.forEachIndexed { _, (key, _) ->
println(key)
}
// Multi-line lambda (the last expression is the return value)
val process: (Int) -> String = { n ->
val abs = if (n < 0) -n else n
val label = if (abs > 10) "large" else "small"
"$abs is $label"
}
println(process(-15)) // 15 is large
println(process(5)) // 5 is small
// Use return@label to exit only the lambda
val numbers = listOf(1, 2, 3, 4, 5)
numbers.forEach {
if (it == 3) return@forEach // Exits only the lambda (equivalent to continue)
println(it)
}
// Outputs 1, 2, 4, 5
// Store a lambda in a variable and use it later
val operations: List<(Int) -> Int> = listOf(
{ it * 2 },
{ it + 10 },
{ it * it }
)
println(operations.map { it(4) }) // [8, 14, 16]
}
lambda_expression.kt
kotlinc lambda_expression.kt -include-runtime -d lambda_expression.jar java -jar lambda_expression.jar 8 [2, 4, 6, 8, 10] [2, 4, 6] a: 1 b: 2 c: 3 a b c 15 is large 5 is small 1 2 4 5 [8, 14, 16]
Common Mistakes
sample_lambda_mistakes.kt
fun main() {
// Trying to non-local return from a lambda in a non-inline function
// listOf(1, 2, 3).forEach { return } → Compile error (non-local return requires inline)
// Use return@forEach to exit only the lambda
listOf(1, 2, 3).forEach {
if (it == 2) return@forEach
println(it)
}
// Using it when there are multiple parameters
// val pairs = listOf(1 to "one", 2 to "two")
// pairs.forEach { println(it.first) } // it refers to the whole Pair (compiles but unclear)
// Give explicit names to parameters for clarity
val pairs = listOf(1 to "one", 2 to "two")
pairs.forEach { (num, word) -> println("$num: $word") }
val process: (Int) -> String = { n ->
// return "$n!" → Compile error (return inside a lambda is a non-local return)
"$n!" // The last expression is the return value
}
println(process(5)) // 5!
// Relying on type inference for a lambda without a type annotation
// val fn = { it * 2 } → Compile error (cannot infer the type of it)
val fn: (Int) -> Int = { it * 2 }
println(fn(4)) // 8
}
The command looks like this:
kotlinc sample_lambda_mistakes.kt -include-runtime -d sample_lambda_mistakes.jar java -jar sample_lambda_mistakes.jar 1 3 1: one 2: two 5! 8
Notes
Lambda expressions are frequently used in Kotlin for collection operations and higher-order function calls. When a lambda has a single parameter, you can refer to it with it, and trailing lambda syntax makes your code more readable.
If you want to return from the outer function inside a lambda, the outer function must be an inline function — otherwise it results in a compile error. To exit only the lambda, attach a label such as return@forEach.
For how higher-order functions work, see Higher-Order Functions. For inlining lambdas, see inline Functions.
If you find any errors or copyright issues, please contact us.