kotlin:函数式参数

在 Kotlin 中,函数式编程的核心特性之一就是将函数作为"一等公民",这意味着函数可以像其他数据类型(如 StringInt)一样,被当作参数传递、赋值给变量,或作为返回值。

这通常被称为 高阶函数

1. 基本概念:高阶函数

高阶函数是指将函数作为参数或返回值的函数。

复制代码
// 一个接受函数作为参数的高阶函数
fun calculate(x: Int, y: Int, operation: (Int, Int) -> Int): Int {
    return operation(x, y) // 调用传入的函数
}

// 使用:传递一个 Lambda 表达式(函数字面值)
val sum = calculate(10, 5) { a, b -> a + b } // 结果是 15
val product = calculate(10, 5) { a, b -> a * b } // 结果是 50

2. 函数类型

函数式参数的语法是 (参数类型) -> 返回类型

复制代码
// 定义一个函数类型变量
val greet: (String) -> Unit = { name -> println("Hello, $name!") }

// 作为参数类型
fun executeAction(action: () -> Unit) {
    action()
}

3. 传递函数式参数的几种方式

方式一:Lambda 表达式(最常用)
复制代码
listOf(1, 2, 3).filter { it > 1 } // `it > 1` 是一个 Lambda
方式二:函数引用(::

如果已经有一个命名函数,可以直接引用它。

复制代码
fun isEven(number: Int): Boolean = number % 2 == 0

val numbers = listOf(1, 2, 3, 4)
val evens = numbers.filter(::isEven) // 引用现有函数
方式三:匿名函数

与 Lambda 类似,但可以更明确地指定返回类型。

复制代码
numbers.filter(fun(num): Boolean {
    return num % 2 == 0
})

4. 有用的语法糖

  • 最后一个 Lambda 可移出括号:如果函数的最后一个参数是函数类型,Lambda 可以放在圆括号外。

    复制代码
    // 这两种写法等价
    calculate(10, 5, { a, b -> a + b })
    calculate(10, 5) { a, b -> a + b } // 更推荐,更清晰
  • 唯一参数是 Lambda 时可省略括号:如果函数只有一个参数且是函数类型,调用时可以直接写 Lambda。

    复制代码
    run { println("执行!") } // `run` 的函数签名是 `run(block: () -> R)`
  • 隐式参数 it :当 Lambda 只有一个参数时,可以省略声明,用 it指代。

    复制代码
    listOf("A", "B").forEach { println(it) } // 而不是 { str -> println(str) }

5. 带接收者的函数类型

这是 Kotlin 中 DSL(领域特定语言)和扩展函数式编程的基础。例如 applywithrun标准库函数。

复制代码
// 类型:`String.() -> Unit` 表示在 `String` 的上下文中执行的函数
fun buildString(action: StringBuilder.() -> Unit): String {
    val sb = StringBuilder()
    sb.action() // 在 sb 的上下文中调用传入的 Lambda
    return sb.toString()
}

val result = buildString {
    append("Hello, ") // 这里的 `this` 是 StringBuilder 实例
    append("World!")
}
// result 为 "Hello, World!"

总结

Kotlin 的函数式参数是其现代、简洁、表达力强的关键。它广泛应用于:

  • 集合操作filtermapforEach

  • 作用域函数letapplyalsorunwith

  • 回调处理和异步编程

  • 构建类型安全的 DSL

掌握它,能让你写出更声明式、更易读的代码。

相关推荐
AI多Agent协作实战派1 小时前
AI多Agent协作系统实战(十七):凌晨4点,我的AI系统在“假装工作“——3个bug同时爆炸的5小时
java·前端·bug
gaolei_eit1 小时前
Java+Ai+vue
java·spring·maven
qq_2518364571 小时前
基于java Web 动漫视频网站毕业论文
java·开发语言·前端
LayZhangStrive2 小时前
JUC相关的函数、注解、变量杂记
java·面试·多线程·juc
未秃头的程序猿2 小时前
给公司做了个AI客服Agent,用的Spring AI 1.0,3天上线领导拍板了
java·后端·ai编程
来一碗刘肉面2 小时前
栈的应用(表达式求值)
数据结构·算法
曹牧2 小时前
Eclipse 批量文本替换
java·ide·eclipse
程序员清风2 小时前
OpenAI官方发布最新提示词技巧!
java·后端·面试
一只枫林2 小时前
MySQL内、外连接知识点汇总
java·前端·数据库
梅头脑2 小时前
写了3年CRUD,volatile和synchronized的区别还是答不清——直到我画出了这张三性两锁边界图
java