Kotlin 高阶函数 —— 新手入门指南

高阶函数是Kotlin中一个强大且灵活的特性,它允许函数作为参数传递或作为返回值返回。这种函数式编程的特性让代码更加简洁、表达力更强。

什么是高阶函数

高阶函数是指以函数作为参数或返回值的函数。在Kotlin中,函数是一等公民,可以像其他数据类型一样被传递和操作。

基本语法

函数作为参数

kotlin 复制代码
fun calculate(x: Int, y: Int, operation: (Int, Int) -> Int): Int {
    return operation(x, y)
}

fun sum(a: Int, b: Int) = a + b

fun main() {
    val result = calculate(10, 5, ::sum)
    println(result) // 输出 15
}

函数作为返回值

kotlin 复制代码
fun getOperation(type: String): (Int, Int) -> Int {
    return when (type) {
        "sum" -> { a, b -> a + b }
        "subtract" -> { a, b -> a - b }
        else -> { _, _ -> 0 }
    }
}

fun main() {
    val operation = getOperation("sum")
    println(operation(10, 5)) // 输出 15
}

Lambda表达式

Kotlin中常用Lambda表达式来简化高阶函数的使用:

kotlin 复制代码
fun calculate(x: Int, y: Int, operation: (Int, Int) -> Int): Int {
    return operation(x, y)
}

fun main() {
    // 使用Lambda表达式
    val sumResult = calculate(10, 5) { a, b -> a + b }
    val multiplyResult = calculate(10, 5) { a, b -> a * b }
    
    println(sumResult) // 15
    println(multiplyResult) // 50
}

常见高阶函数

Kotlin标准库提供了许多有用的高阶函数:

1、forEach

kotlin 复制代码
fun main() {
    val numbers = listOf(1, 2, 3, 4, 5)
    numbers.forEach { println(it) }
}

2、map

kotlin 复制代码
fun main() {
    val numbers = listOf(1, 2, 3)
    val doubled = numbers.map { it * 2 }
    println(doubled) // [2, 4, 6]
}

3、filter

kotlin 复制代码
fun main() {
    val numbers = listOf(1, 2, 3, 4, 5, 6)
    val evens = numbers.filter { it % 2 == 0 }
    println(evens) // [2, 4, 6]
}

4、reduce

kotlin 复制代码
fun main() {
    val numbers = listOf(1, 2, 3, 4)
    val sum = numbers.reduce { acc, num -> acc + num }
    println(sum) // 10
}

5、fold

kotlin 复制代码
fun main() {
    val numbers = listOf(1, 2, 3, 4)
    val sum = numbers.fold(10) { acc, num -> acc + num }
    println(sum) // 20 (初始值10 + 1+2+3+4)
}

带接收者的函数类型

Kotlin支持带接收者的函数类型,这在DSL(领域特定语言)设计中特别有用:

kotlin 复制代码
class HTML {
    fun body() { println("body") }
    fun div() { println("div") }
}

fun html(init: HTML.() -> Unit): HTML {
    val html = HTML()
    html.init()
    return html
}

fun main() {
    html {
        body()
        div()
    }
}

内联函数

使用inline关键字可以优化高阶函数的性能,避免Lambda表达式带来的运行时开销:

kotlin 复制代码
inline fun measureTime(block: () -> Unit) {
    val start = System.currentTimeMillis()
    block()
    val end = System.currentTimeMillis()
    println("Execution time: ${end - start} ms")
}

fun main() {
    measureTime {
        // 一些耗时操作
        Thread.sleep(1000)
    }
}

注意事项

  1. 性能考虑:非内联的高阶函数会创建额外的对象,可能影响性能
  2. 可读性:适度使用高阶函数可以提高代码可读性,但过度使用可能使代码难以理解
  3. 调试难度:Lambda表达式中的异常堆栈跟踪可能不如普通函数清晰

实际应用示例

回调函数

kotlin 复制代码
fun downloadData(url: String, callback: (String) -> Unit) {
    // 模拟网络请求
    Thread {
        Thread.sleep(1000)
        callback("Data from $url")
    }.start()
}

fun main() {
    downloadData("https://example.com") { data ->
        println("Received: $data")
    }
    println("Waiting for data...")
}

策略模式

kotlin 复制代码
fun applyDiscount(price: Double, strategy: (Double) -> Double): Double {
    return strategy(price)
}

fun main() {
    val regularDiscount = { price: Double -> price * 0.9 }
    val vipDiscount = { price: Double -> price * 0.7 }
    
    println(applyDiscount(100.0, regularDiscount)) // 90.0
    println(applyDiscount(100.0, vipDiscount)) // 70.0
}

高阶函数是Kotlin函数式编程的核心特性之一,合理使用可以大幅提升代码的简洁性和表达力。

更多分享

  1. 一文带你吃透Kotlin中 lateinit 和 by lazy 的区别和用法
  2. Kotlin 作用域函数(let、run、with、apply、also)的使用指南
  3. Kotlin 操作符与集合/数组方法详解------新手指南
  4. Kotlin日常高效编程技巧和作用域函数的使用。
相关推荐
阿巴斯甜6 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker7 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95278 小时前
Andorid Google 登录接入文档
android
黄林晴9 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android