Expresiones Lambda
## Objetivos de Aprendizaje
- Comprender la sintaxis de lambdas
- Trabajar con funciones de orden superior
- Usar lambdas de la biblioteca estándar
- Dominar referencias a funciones
- Aprender sobre funciones inline
## Sintaxis de Lambda
### Lambda Básica
```kotlin
fun main() {
// Lambda expression
val sum = { a: Int, b: Int -> a + b }
println(sum(3, 4)) // 7
}
```
### Sintaxis de Expresión Lambda
```text
{ parameters -> body }
```
```kotlin
fun main() {
// Multiple parameters
val multiply = { a: Int, b: Int -> a * b }
println(multiply(3, 4)) // 12
// Single parameter - use `it`
val double = { x: Int -> x * 2 }
val double2: (Int) -> Int = { it * 2 }
println(double(5)) // 10
println(double2(5)) // 10
// No parameters
val greet = { -> println("Hello!") }
greet() // Hello!
// Unit return
val printAndReturn = { x: Int ->
println("Value: $x")
}
}
```
### Anotaciones de Tipo
```kotlin
fun main() {
// Explicit type
val sum: (Int, Int) -> Int = { a, b -> a + b }
// Nullable function type
var maybePrint: ((Int) -> Unit)? = null
maybePrint = { x -> println(x) }
maybePrint?.invoke(42)
}
```
## Funciones de Orden Superior
Una función de orden superior toma funciones como parámetros o retorna una función:
```kotlin
// Function as parameter
fun operation(a: Int, b: Int, op: (Int, Int) -> Int): Int {
return op(a, b)
}
fun main() {
val result = operation(10, 5) { x, y -> x + y }
println(result) // 15
val difference = operation(10, 5) { x, y -> x - y }
println(difference) // 5
}
```
### Tipo de Retorno de Función
```kotlin
fun multiplier(factor: Int): (Int) -> Int {
return { x -> x * factor }
}
fun main() {
val double = multiplier(2)
val triple = multiplier(3)
println(double(5)) // 10
println(triple(5)) // 15
}
```
## Lambdas de Biblioteca Estándar
### with
```kotlin
fun main() {
val person = Person().apply {
name = "Alice"
age = 30
}
// with - call multiple methods on same object
val info = with(person) {
"$name is $age years old"
}
println(info) // Alice is 30 years old
}
class Person {
var name: String = ""
var age: Int = 0
}
```
### apply
```kotlin
fun main() {
val person = Person().apply {
name = "Bob"
age = 25
}
println("${person.name}, ${person.age}") // Bob, 25
}
```
### let
```kotlin
fun main() {
// let - transform and return
val length = "Hello".let {
println("String: $it")
it.length
}
println("Length: $length")
// With null safety
val name: String? = "Alice"
name?.let {
println("Name is $it")
}
}
```
### run
```kotlin
fun main() {
val result = "Hello".run {
println("Running on $this")
this.uppercase()
}
println(result) // HELLO
// With block
val person = Person().run {
name = "Charlie"
age = 35
this
}
println("${person.name}, ${person.age}")
}
```
### also
```kotlin
fun main() {
// also - perform additional actions
val numbers = mutableListOf(1, 2, 3)
.also { println("Created list: $it") }
.also { it.add(4) }
.also { println("Added 4: $it") }
println(numbers) // [1, 2, 3, 4]
}
```
## Referencias a Funciones
### Referencia a Método
```kotlin
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
// Method reference
numbers.forEach(::println)
// Reference to top-level function
numbers.forEach(::printNumber)
// Reference to bound method
val person = Person("Alice")
val printName = person::printInfo
printName()
}
fun printNumber(n: Int) {
print("$n ")
}
class Person(val name: String) {
fun printInfo() {
println("Name: $name")
}
}
```
### Referencia a Constructor
```kotlin
class Person(val name: String)
fun main() {
// Constructor reference
val factory: (String) -> Person = ::Person
val person = factory("Alice")
println(person.name) // Alice
}
```
### Referencia a Propiedad
```kotlin
var x = 10
fun main() {
println(::x.get()) // 10
::x.set(20)
println(::x.get()) // 20
// In collections
val strings = listOf("hello", "world")
val lengths = strings.map { it.length }
val lengths2 = strings.map(String::length)
println(lengths) // [5, 5]
println(lengths2) // [5, 5]
}
```
## Funciones Inline
`inline` le dice al compilador que inserte el cuerpo de la función en el sitio de llamada:
```kotlin
inline fun measureTime(block: () -> Unit): Long {
val start = System.currentTimeMillis()
block()
return System.currentTimeMillis() - start
}
fun main() {
val time = measureTime {
Thread.sleep(100)
}
println("Took $time ms")
}
```
### noinline y crossinline
```kotlin
// noinline - don't inline a specific parameter
inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) {
inlined()
notInlined()
}
// crossinline - must be called but can't have non-local return
inline fun bar(crossinline f: () -> Unit) {
f() // Must call f
}
```
## Funciones Comunes de Biblioteca Estándar
### map
```kotlin
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
val doubled = numbers.map { it * 2 }
println(doubled) // [2, 4, 6, 8, 10]
val names = listOf("Alice", "Bob", "Charlie")
val upper = names.map { it.uppercase() }
println(upper) // [ALICE, BOB, CHARLIE]
}
```
### filter
```kotlin
fun main() {
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val evens = numbers.filter { it % 2 == 0 }
println(evens) // [2, 4, 6, 8, 10]
val greaterThan5 = numbers.filter { it > 5 }
println(greaterThan5) // [6, 7, 8, 9, 10]
}
```
### sorted
```kotlin
fun main() {
val numbers = listOf(5, 2, 8, 1, 9)
println(numbers.sorted()) // [1, 2, 5, 8, 9]
println(numbers.sortedDescending()) // [9, 8, 5, 2, 1]
val words = listOf("banana", "apple", "cherry")
println(words.sorted()) // [apple, banana, cherry]
}
```
### take y drop
```kotlin
fun main() {
val numbers = (1..10).toList()
println(numbers.take(3)) // [1, 2, 3]
println(numbers.takeLast(3)) // [8, 9, 10]
println(numbers.drop(3)) // [4, 5, 6, 7, 8, 9, 10]
println(numbers.dropLast(3)) // [1, 2, 3, 4, 5, 6, 7]
}
```
## Resumen
- Lambdas: `{ parameters -> body }` o `{ it }` para un solo parámetro
- Las funciones de orden superior aceptan o retornan funciones
- `with`, `apply`, `let`, `run`, `also` son funciones de ámbito
- `::` crea referencias a funciones
- `inline` inserta el cuerpo de la función en el sitio de llamada
- `map`, `filter`, `sorted`, `take`, `drop` son operaciones comunes
- Las lambdas hacen el código más conciso y funcional
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →