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

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

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

相关推荐
mmsx18 小时前
Android 上的 AI 对话链路:流式响应、SSE 解析与三级降级
android·kotlin
YB137519 小时前
Kotlin 引用操作符::
kotlin
维克兜率天2 天前
【维克】弹性策略:用“乖离率“捕捉超跌反弹
android·开发语言·python·深度学习·kotlin·量化
传奇开心果编程2 天前
【用案例学Material 3 Expressive】第1课:从一封邮件开始,感受安卓设计新语言的表现力
android·学习·ui·kotlin·android jetpack
mmsx2 天前
Android 状态保持:进程被杀、旋屏与后台任务的存活术
android·kotlin
传奇开心果编程2 天前
【Jetpack Compose进阶学与练】第14课:系列收尾复习总结;Compose项目常见坑点汇总;学习路线与后续学习方向
android·学习·ui·kotlin·android jetpack
花开路口3 天前
线程安全完全指南:从 Java 到 Kotlin,一文吃透并发编程
java·kotlin
hai_android3 天前
子 View 被压小时,如何向父容器"告状"?——MEASURED_STATE_TOO_SMALL 向上传递机制
android·kotlin·android jetpack
怪奇云呼军3 天前
从 ElevenLabs 看工具调用:闪电智能 Voice Agent 的企业集成验收设计
android·大数据·运维·服务器·网络·人工智能·kotlin
mmsx3 天前
Android UI 复用体系:泛型基类、骨架与插槽
android·kotlin