In Kotlin, lambdas and anonymous functions are fundamental features used for functional programming. They allow you to write concise and flexible code. Here’s an overview on how to use them:
1. Lambda Expressions
A lambda is an anonymous function defined using curly braces {}
. It’s a short way to declare a function without explicitly naming it.
Syntax:
{ parameter(s) -> body }
Example:
// Lambda that takes two integers and returns their sum
val sum = { a: Int, b: Int -> a + b }
// Using the lambda
println(sum(3, 5)) // Output: 8
2. Single-Parameter Lambdas
If a lambda has only one parameter, you can omit the parameter declaration and use it
instead (an implicit name for the parameter).
Example:
val square = { it * it } // 'it' is the implicit name for the parameter
println(square(4)) // Output: 16
3. Passing Lambdas to Higher-Order Functions
You can pass lambdas as arguments to functions that take other functions as parameters, referred to as higher-order functions.
Example:
fun calculate(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
return operation(a, b)
}
// Passing a lambda
val result = calculate(4, 5) { x, y -> x + y }
println(result) // Output: 9
4. Anonymous Functions
An anonymous function is similar to a lambda but explicitly uses the function keyword. It allows you to specify return types.
Example:
val multiply = fun(a: Int, b: Int): Int {
return a * b
}
println(multiply(3, 4)) // Output: 12
5. Differences Between Lambdas and Anonymous Functions
- Lambdas implicitly infer the return type (using the last expression), whereas anonymous functions can have explicitly declared return types.
- Lambdas cannot use a
return
keyword for the enclosing function, while anonymous functions can.
6. Inline Lambda Usage
For functions like map
, filter
, or forEach
, lambdas can be used to process collections concisely. These functions come from Kotlin’s standard library.
Example:
val numbers = listOf(1, 2, 3, 4, 5)
// Transform each element using a lambda
val doubled = numbers.map { it * 2 }
println(doubled) // Output: [2, 4, 6, 8, 10]
// Filter using a lambda
val evens = numbers.filter { it % 2 == 0 }
println(evens) // Output: [2, 4]
7. Lambda as Return Type
You can assign functions returning lambdas to variables.
Example:
fun createMultiplier(factor: Int): (Int) -> Int {
return { number -> number * factor }
}
val timesThree = createMultiplier(3)
println(timesThree(5)) // Output: 15
8. Default Parameters in Lambda
While lambdas themselves don’t support default arguments, you can achieve a similar effect by wrapping them in a function that provides default behavior.
Example:
fun greet(name: String, message: (String) -> String = { "Hello, $it!" }) {
println(message(name))
}
// Using the default lambda
greet("John") // Output: Hello, John!
// Customizing the lambda
greet("John") { "Hi, $it! Welcome back!" } // Output: Hi, John! Welcome back!
9. Higher-Order Functions Inline and Crossinline
When using lambdas in performance-critical situations, consider using the inline
or crossinline
modifier, which instructs the compiler to inline the lambda directly into the calling function.
Example:
inline fun perform(action: () -> Unit) {
action()
}
perform {
println("This lambda was inlined!")
}
Summary
- Lambdas:
{ parameter(s) -> body }
- Single-parameter lambdas can use
it
as the implicit name. - Anonymous functions use the
fun
keyword and can declare explicit return types. - You can pass lambdas to higher-order functions for concise and flexible processing.
- Use collections functions like
map
,filter
, andforEach
to apply lambdas efficiently.
The combination of lambdas and Kotlin’s higher-order functions lets you write clear and concise functional code!