一、基本概念与语法
Kotlin 函数引用(Function Reference)通过双冒号操作符 ::
实现,允许将具名函数作为高阶函数的参数或返回值 使用,其本质是将函数转换为函数类型实例14。
kotlin
fun sum(x: Int, y: Int) = x + y
val sumRef: (Int, Int) -> Int = ::sum // 函数引用赋值给变量:ml-citation{ref="4" data="citationList"}
二、核心使用场景
-
替代 Lambda 表达式
当 Lambda 仅调用单一具名函数时,可用函数引用简化代码,提升可读性46:
erlanglistOf(1, 3, 5).forEach(::println) // 替代 { x -> println(x) }:ml-citation{ref="3" data="citationList"}
-
动态传递函数逻辑
函数引用可作为参数传递给高阶函数,实现灵活的行为控制:
kotlinfun applyOp(x: Int, y: Int, op: (Int, Int) -> Int) = op(x, y) applyOp(2, 3, ::sum) // 输出 5:ml-citation{ref="4" data="citationList"}
-
构建函数工厂
函数类型作为返回值时,可基于条件返回不同函数引用:
kotlinfun getMathOp(isAdd: Boolean): (Int, Int) -> Int = if (isAdd) ::sum else ::subtract:ml-citation{ref="1" data="citationList"}
三、不同引用类型的语法
引用类型 | 语法示例 | 说明 |
---|---|---|
类静态方法 | MyClass::methodName |
需类名限定,参数包含类实例35 |
实例方法 | myInstance::methodName |
绑定实例,调用时无需传递接收者35 |
扩展函数 | String::isEmpty |
接收者类型作为第一个参数34 |
构造函数 | ::MyClass |
生成类实例的工厂函数5 |
四、注意事项与最佳实践
-
类型匹配严格性
函数引用需与目标函数类型完全匹配(参数数量、类型、返回值),否则编译报错46。
sql// 错误:sum 函数类型为 (Int, Int) -> Int,与 (Int) -> Int 不匹配 val invalidRef: (Int) -> Int = ::sum
-
反射依赖库问题
若需通过反射获取函数引用元信息(如 KFunction),需添加
kotlin-reflect
依赖5。 -
性能优化建议
- 优先使用函数引用替代匿名类或反射调用;
- 高频调用的场景可结合
inline
关键字消除 Lambda 开销6。
五、综合示例
kotlin
kotlinCopy Code
// 类方法引用
class Logger(val tag: String) {
fun log(msg: String) = println("$tag: $msg")
}
val logger = Logger("App")
val logRef: (String) -> Unit = logger::log // 绑定实例的引用:ml-citation{ref="3,5" data="citationList"}
// 扩展函数引用
fun String?.safeIsEmpty(): Boolean = this.isNullOrEmpty()
val isEmptyRef: (String?) -> Boolean = String?::safeIsEmpty:ml-citation{ref="3,4" data="citationList"}
// 函数引用作为返回值
fun createComparator(reverse: Boolean): Comparator<Int> =
if (reverse) ::compareDescending else ::compareAscending:ml-citation{ref="6" data="citationList"}
案例
kotlin
const val LOGIN_NAME1 = "xingmo"
const val LOGIN_PWD2 = "123456"
fun main(){
login("xingmo","123456",::methodResponseResult) //实例方法的引用
login("xingmo","123456",obj2)
logRef.invoke("Hello")
}
// 类方法引用
class Logger(val tag: String) {
fun log(msg: String) = println("$tag: $msg")
}
val logger = Logger("App")
val logRef: (String) -> Unit = logger::log // 绑定实例的引用:ml-citation{ref="3,5" data="citationList"}
val obj1 = :: methodResponseResult //函数引用赋值给变量
val obj2 = obj1
//函数实现部分
fun methodResponseResult(msg: String, code: String) {
println("最终登录的成果是:msg:$msg, code:$code")
}
const val USER_NAME_SAVE_DB4 = "xingmo"
const val USER_PWD_SAVE_DB4= "123456"
inline fun login(name: String, pwd: String, responseResult: (String, String) -> Unit) {
if (USER_NAME_SAVE_DB4 == name && USER_PWD_SAVE_DB4 == pwd) {
// 登录成功
// 做很多的事情 校验成功信息等
responseResult("登录成功", 200)
// ...
} else {
// 登录失败
// 做很多的事情 登录失败的逻辑处理
// ...
responseResult("登录失败错了", 444)
}
}
总结 :Kotlin 函数引用通过 ::
操作符实现函数逻辑的一级公民化,适用于代码简化、动态逻辑分发等场景,需注意类型匹配和性能优化