2-2-2 快速掌握Kotlin-函数&Lambda

Kotlin 函数与 Lambda 表达式

1. 函数(Functions)

函数定义

kotlin 复制代码
// 1. 基本函数
fun greet(name: String): String {
    return "Hello, $name!"
}

// 2. 表达式函数体(单表达式函数)
fun add(a: Int, b: Int): Int = a + b

// 3. 类型推断
fun multiply(a: Int, b: Int) = a * b

// 4. 无返回值(Unit 可省略)
fun printMessage(msg: String): Unit {
    println(msg)
}
// 等价于
fun printMessage(msg: String) {
    println(msg)
}

函数参数

kotlin 复制代码
// 1. 默认参数
fun createUser(name: String, age: Int = 18, city: String = "Beijing") {
    println("Name: $name, Age: $age, City: $city")
}

// 2. 命名参数
createUser(name = "Alice", city = "Shanghai")  // age 使用默认值 18

// 3. 可变参数
fun sum(vararg numbers: Int): Int {
    return numbers.sum()
}
sum(1, 2, 3, 4, 5)

// 4. 函数参数
fun calculate(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
    return operation(a, b)
}

特殊函数

kotlin 复制代码
// 1. 扩展函数
fun String.addExclamation(): String = "$this!"

val message = "Hello".addExclamation()  // "Hello!"

// 2. 中缀函数
infix fun Int.times(str: String) = str.repeat(this)
val result = 3 times "Hi"  // "HiHiHi"

// 3. 内联函数(用于高阶函数优化)
inline fun measureTime(block: () -> Unit) {
    val start = System.currentTimeMillis()
    block()
    val end = System.currentTimeMillis()
    println("Time: ${end - start}ms")
}

// 4. 尾递归函数
tailrec fun factorial(n: Int, accumulator: Int = 1): Int {
    return if (n <= 1) accumulator else factorial(n - 1, n * accumulator)
}

// 5. 局部函数
fun outerFunction(x: Int) {
    fun innerFunction(y: Int): Int {
        return x + y  // 可以访问外部函数的参数
    }
    println(innerFunction(5))
}

2. Lambda 表达式

基本语法

kotlin 复制代码
// 1. 基本形式
val sum: (Int, Int) -> Int = { a, b -> a + b }

// 2. 类型推断
val multiply = { a: Int, b: Int -> a * b }

// 3. 单参数 lambda(可用 it)
val double: (Int) -> Int = { it * 2 }
val isEven: (Int) -> Boolean = { it % 2 == 0 }

// 4. 无参数 lambda
val sayHello: () -> Unit = { println("Hello!") }

// 5. 作为函数参数
listOf(1, 2, 3).forEach { println(it) }

// 6. 带接收者的 lambda(常用于 DSL)
val stringBuilder = StringBuilder().apply {
    append("Hello")
    append(" ")
    append("World")
}

Lambda 与集合操作

kotlin 复制代码
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

// 1. filter - 过滤
val evens = numbers.filter { it % 2 == 0 }  // [2, 4, 6, 8, 10]

// 2. map - 转换
val squares = numbers.map { it * it }  // [1, 4, 9, 16, 25, ...]

// 3. reduce - 累积操作
val sum = numbers.reduce { acc, num -> acc + num }  // 55

// 4. fold - 带初始值的累积
val product = numbers.fold(1) { acc, num -> acc * num }

// 5. takeWhile/dropWhile - 条件截取
val lessThan5 = numbers.takeWhile { it < 5 }  // [1, 2, 3, 4]
val from5 = numbers.dropWhile { it < 5 }     // [5, 6, 7, 8, 9, 10]

// 6. sortedBy - 排序
val strings = listOf("apple", "banana", "cherry")
val sortedByLength = strings.sortedBy { it.length }  // ["apple", "cherry", "banana"]

// 7. groupBy - 分组
val groupedByParity = numbers.groupBy { 
    if (it % 2 == 0) "even" else "odd" 
}
// 结果: {"odd"=[1,3,5,7,9], "even"=[2,4,6,8,10]}

// 8. flatMap - 扁平化映射
val nested = listOf(listOf(1, 2), listOf(3, 4), listOf(5, 6))
val flat = nested.flatMap { it }  // [1, 2, 3, 4, 5, 6]

3. 高阶函数(Higher-Order Functions)

kotlin 复制代码
// 1. 函数作为参数
fun processNumbers(
    numbers: List<Int>,
    filter: (Int) -> Boolean,
    transform: (Int) -> Int
): List<Int> {
    return numbers.filter(filter).map(transform)
}

val result = processNumbers(
    numbers = listOf(1, 2, 3, 4, 5),
    filter = { it > 2 },
    transform = { it * 10 }
)  // [30, 40, 50]

// 2. 函数作为返回值
fun getOperation(type: String): (Int, Int) -> Int {
    return when (type) {
        "add" -> { a, b -> a + b }
        "multiply" -> { a, b -> a * b }
        else -> { a, b -> a - b }
    }
}

val operation = getOperation("add")
println(operation(5, 3))  // 8

// 3. 组合函数
fun compose(f: (Int) -> Int, g: (Int) -> Int): (Int) -> Int {
    return { x -> f(g(x)) }
}

val addTwo = { x: Int -> x + 2 }
val timesThree = { x: Int -> x * 3 }
val composed = compose(addTwo, timesThree)
println(composed(5))  // 17 = (5 * 3) + 2

// 4. 带接收者的函数类型
fun buildString(builderAction: StringBuilder.() -> Unit): String {
    val sb = StringBuilder()
    sb.builderAction()
    return sb.toString()
}

val s = buildString {
    append("Hello, ")
    append("World!")
}  // "Hello, World!"

4. 作用域函数(Scope Functions)

kotlin 复制代码
data class Person(var name: String, var age: Int, var city: String)

val person = Person("Alice", 25, "New York")

// 1. let - 用 it 引用对象,返回 lambda 结果
val nameLength = person.let {
    it.name = it.name.capitalize()
    it.name.length  // 返回这个
}

// 2. run - 用 this 引用对象,返回 lambda 结果
val description = person.run {
    age += 1  // 可以直接访问属性
    "$name is $age years old from $city"  // 返回这个
}

// 3. with - 类似 run,但作为独立函数
with(person) {
    println("Processing $name")
    city = "London"
}

// 4. apply - 用 this 引用对象,返回对象本身
val modifiedPerson = person.apply {
    name = "Bob"
    age = 30
}  // 返回 person 对象本身

// 5. also - 用 it 引用对象,返回对象本身
val personCopy = person.also {
    println("Before: $it")
    it.age = 26
}.also {
    println("After: $it")
}

5. Lambda 的特殊语法

kotlin 复制代码
// 1. 最后参数是 lambda 时可以放到括号外
fun executeWithDelay(delay: Long, action: () -> Unit) {
    Thread.sleep(delay)
    action()
}

// 传统调用
executeWithDelay(1000, { println("Hello") })

// 简化调用(推荐)
executeWithDelay(1000) {
    println("Hello")
}

// 2. 如果 lambda 是唯一参数,可以省略括号
listOf(1, 2, 3).forEach { println(it) }

// 3. 带标签的 return
listOf(1, 2, 3, 4, 5).forEach {
    if (it == 3) return@forEach  // 只从这个 lambda 返回
    println(it)
}
// 输出: 1 2 4 5

// 4. 匿名函数(类似 lambda,但 return 行为不同)
listOf(1, 2, 3).forEach(fun(value) {
    if (value == 2) return  // 从匿名函数返回,继续循环
    println(value)
})
// 输出: 1 3

6. 实用示例

kotlin 复制代码
// 1. DSL 构建器
class HTML {
    fun body() { println("Creating body") }
    fun div(block: Div.() -> Unit) { Div().apply(block) }
}

class Div {
    fun p(text: String) { println("Paragraph: $text") }
    fun a(href: String, text: String) { println("Link: <a href='$href'>$text</a>") }
}

fun html(block: HTML.() -> Unit): HTML {
    return HTML().apply(block)
}

html {
    body()
    div {
        p("Hello World")
        a("https://kotlinlang.org", "Kotlin")
    }
}

// 2. 缓存计算结果
fun <T, R> memoize(fn: (T) -> R): (T) -> R {
    val cache = mutableMapOf<T, R>()
    return { key ->
        cache.getOrPut(key) { fn(key) }
    }
}

val expensiveCalculation = memoize { n: Int ->
    println("Calculating for $n")
    // 模拟耗时计算
    (1..n).sum()
}

println(expensiveCalculation(5))  // 计算并缓存
println(expensiveCalculation(5))  // 直接使用缓存

7. 函数引用

kotlin 复制代码
// 1. 函数引用
fun isEven(n: Int) = n % 2 == 0
val numbers = listOf(1, 2, 3, 4, 5)

// 使用函数引用
val evens = numbers.filter(::isEven)

// 2. 属性引用
data class User(val name: String, val age: Int)
val users = listOf(User("Alice", 25), User("Bob", 30))

// 按属性引用排序
val sortedByName = users.sortedBy(User::name)
val ages = users.map(User::age)

// 3. 构造函数引用
class Person(val name: String)

val createPerson = ::Person
val person = createPerson("Charlie")

// 4. 绑定函数引用
val alice = User("Alice", 25)
val isAliceAdult = alice::isAdult
println(isAliceAdult())  // true

fun User.isAdult() = age >= 18

最佳实践

  1. 优先使用表达式函数体:当函数体很简单时
  2. 合理使用默认参数:减少重载函数数量
  3. 善用作用域函数:让代码更简洁清晰
  4. 链式调用时考虑性能:避免创建过多中间集合
  5. 使用函数引用:提高代码可读性
  6. 内联高阶函数:减少 lambda 开销
  7. 注意 lambda 中的返回行为:使用标签或匿名函数控制

Kotlin 的函数和 lambda 表达式是其函数式编程能力的核心,它们使代码更加简洁、表达力更强,并且支持多种编程范式。

相关推荐
成都大菠萝2 小时前
2-1-1 快速掌握Kotlin-kotlin中变量&语句&表达式
android
CC.GG2 小时前
【C++】STL----封装红黑树实现map和set
android·java·c++
renke33642 小时前
Flutter 2025 跨平台工程体系:从 iOS/Android 到 Web/Desktop,构建真正“一次编写,全端运行”的产品
android·flutter·ios
儿歌八万首3 小时前
Android 自定义 View :打造一个跟随滑动的丝滑指示器
android
yueqc13 小时前
Android System Lib 梳理
android·lib
Zender Han4 小时前
Flutter 中 AbsorbPointer 与 IgnorePointer 的区别与使用场景详解
android·flutter·ios
Just_Paranoid4 小时前
【Settings】Android 常见外设检测机制
android·sd·usb·camera·keyboard·sim
_李小白4 小时前
【Android FrameWork】延伸阅读:ptrace机制
android