在 Kotlin 中,函数可以作为参数传递给另一个函数 ,这种特性被称为高阶函数
1. 基本语法
定义一个接受函数作为参数的函数:
kotlin
// 参数是一个函数,接受两个 Int 参数并返回 Int
fun calculate(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
return operation(a, b)
}
调用时传递函数(如 Lambda):
javascript
val result = calculate(5, 3) { x, y -> x + y } // 结果为 8
2. 函数参数的类型声明
函数参数的完整语法包括:
- 参数类型 :
(参数类型列表) -> 返回值类型
- 可为空类型 :
((参数类型) -> 返回值类型)?
- 带接收者的函数类型 (类似扩展函数):
String.() -> Unit
示例:
kotlin
// 可空的函数参数,接受 String 并返回 Unit
fun doWithLog(block: ((String) -> Unit)?) {
block?.invoke("Hello")
}
// 带接收者的函数类型
fun buildString(block: StringBuilder.() -> Unit): String {
val sb = StringBuilder()
sb.block() // 在 StringBuilder 上下文中执行 block
return sb.toString()
}
3. 传递函数引用的方式
可以传递 Lambda 、匿名函数 或 已有函数的引用:
kotlin
kotlinCopy Code
// Lambda
calculate(5, 3) { x, y -> x * y }
// 匿名函数
calculate(5, 3, fun(x: Int, y: Int) = x - y)
// 已有函数的引用
fun multiply(a: Int, b: Int) = a * b
calculate(5, 3, ::multiply)
4. 默认参数与命名参数
为函数参数提供默认值:
kotlin
kotlinCopy Code
fun processData(
data: String,
onSuccess: (String) -> Unit = { println("Success: $it") },
onError: (Exception) -> Unit = { e -> println("Error: ${e.message}") }
) {
try {
// 处理 data...
onSuccess(data)
} catch (e: Exception) {
onError(e)
}
}
// 调用时选择性地覆盖部分参数
processData("input", onError = { println("Custom error handling") })
5. 高阶函数的实际应用场景
- 集合操作 :如
filter
、map
。 - 回调机制:异步操作完成后执行回调。
- 自定义 DSL:通过函数参数构建领域特定语言。
示例:
kotlin
// 自定义集合操作
fun List<Int>.customFilter(predicate: (Int) -> Boolean): List<Int> {
val result = mutableListOf<Int>()
for (item in this) {
if (predicate(item)) result.add(item)
}
return result
}
val filtered = listOf(1, 2, 3).customFilter { it > 1 } // [2, 3]
6. 使用 typealias
简化复杂类型
为复杂的函数类型定义别名:
kotlin
typealias Callback = (data: String, error: Exception?) -> Unit
fun fetchData(callback: Callback) {
// 模拟异步获取数据
callback("Data loaded", null)
}
// 调用
fetchData { data, error ->
error?.let { println("Error") } ?: println(data)
}
7.案例展示
kotlin
fun main(){
loginAPI("lhr","123456"){
msg,pwd -> println("登录结果:$msg,返回码:$pwd")
}
}
fun loginAPI(name:String,pwd:String,responseResult:(String,String) -> Unit){
if (name == null || pwd == null) {
TODO("用户名或密码为null") // 出现问题,终止程序
}
// 做很多的校验 前端校验
if (name.length > 3 && pwd.toString().length > 3) {
if (webServiceLogin(name, pwd)) {
responseResult("登录成功", 100)
} else {
responseResult("登录失败", 400)
}
}else{
TODO("用户名或密码不合格")
}
}
fun webServiceLogin(name:String,pwd:String):Boolean{
return if (name == LOGIN_NAME && pwd == LOGIN_PWD) true else false
}
val responseResult:(msg:String,pwd:Int) -> Unit = {msg,pwd -> println("登录结果是 $msg,返回码是 $pwd")}
用Java代码来实现的话如下:
kotlin
package com.lhr.base.s2
const val LOGIN_NAME = "lhr"
const val LOGIN_PWD = "123456"
//定义函数的参数是函数的函数
fun main(){
loginAPI("lhr","123456"){
msg,pwd -> println("登录结果:$msg,返回码:$pwd")
}
}
fun loginAPI(name:String,pwd:String,responseResult:(String,String) -> Unit){
if (name == null || pwd == null) {
TODO("用户名或密码为null") // 出现问题,终止程序
}
// 做很多的校验 前端校验
if (name.length > 3 && pwd.toString().length > 3) {
if (webServiceLogin(name, pwd)) {
responseResult("登录成功", 100)
} else {
responseResult("登录失败", 400)
}
}else{
TODO("用户名或密码不合格")
}
}
fun webServiceLogin(name:String,pwd:String):Boolean{
return if (name == LOGIN_NAME && pwd == LOGIN_PWD) true else false
}
val responseResult:(msg:String,pwd:Int) -> Unit = {msg,pwd -> println("登录结果是 $msg,返回码是 $pwd")}
总结
在 Kotlin 中,函数作为参数提供了极大的灵活性,允许你:
- 通过 Lambda 或函数引用传递行为。
- 定义清晰的回调机制。
- 构建可复用的高阶工具函数。
掌握这一特性可以显著提升代码的表达能力和简洁性。