Kotlin高阶函数初探

在 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. ‌高阶函数的实际应用场景

  • 集合操作 ‌:如 filtermap
  • 回调机制‌:异步操作完成后执行回调。
  • 自定义 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 或函数引用传递行为。
  • 定义清晰的回调机制。
  • 构建可复用的高阶工具函数。

掌握这一特性可以显著提升代码的表达能力和简洁性。

相关推荐
FunnySaltyFish10 小时前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
Kapaseker16 小时前
Compose 进阶—巧用 GraphicsLayer
android·kotlin
Kapaseker2 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
A0微声z4 天前
Kotlin Multiplatform (KMP) 中使用 Protobuf
kotlin
alexhilton4 天前
使用FunctionGemma进行设备端函数调用
android·kotlin·android jetpack
lhDream4 天前
Kotlin 开发者必看!JetBrains 开源 LLM 框架 Koog 快速上手指南(含示例)
kotlin
RdoZam4 天前
Android-封装基类Activity\Fragment,从0到1记录
android·kotlin
Kapaseker5 天前
研究表明,开发者对Kotlin集合的了解不到 20%
android·kotlin
糖猫猫cc5 天前
Kite:两种方式实现动态表名
java·kotlin·orm·kite
如此风景6 天前
kotlin协程学习小计
android·kotlin