kotlin 高阶函数

76 阅读2分钟

1. 高介函数

在 Kotlin 中,高阶函数是指将函数作为参数或者返回值的函数。

  1. 格式:(参数)-> return_type

1.1 定义函数类型

通过关键 typealias 声明一个 函数类型,在其他函数的入参中可以直接使用

//定义了FuncType 这样一个函数类型
typealias FuncType = (Int) -> Int

//processFunction 函数接受 FunType 类型的参数
fun processFunction(func: FuncType) {
    // 在这里可以使用传递进来的函数 func
    println(func(3))
}
//processFunction 函数接受 FunType 类型的参数
inline fun inlineProcessFunction(func: FuncType) {
    // 在这里可以使用传递进来的函数 func
    println(func(3))
}

1.2 将函数作为入参

以下是一个将函数作为参数的高阶函数示例

 //高阶函数:函数作为入参
 fun calculate(num1: Int, num2: Int, operation: (Int, Int) -> Int): Int {
     return operation(num1, num2)
 }
 
 //普通函数
 fun add(num1: Int, num2: Int): Int {
     return num1 + num2
 }
 
 fun main() {
     //第一种:定义一个 add() 函数,将add函数作为参数,传入到 calculate()中
     //::add 是函数引用的一种写法。
     //使用 ::引入add函数,将add 函数作为第三个参数传入到calculate()中
     var sum = calculate(2, 3, ::add)
     //第二种:通过 lambda 表达式的方式,作为第三个参数
     var sum2 = calculate(2, 3) { n1, n2 ->
         n1 + n2
     }
     println("sum = $sum")
     println("sum2 = $sum2")
 
     //定义个无参的 高阶函数 calculate2()
     //通过 lambda 表达式的方式,作为第三个参数, lambda 表达式为无参
     var  sum3 = calculate2(2,3){
         println("执行 calculate2")
     }
     println("sum3 = $sum3")
 
 
 }
 //lambda 表达式不需要参数
 fun calculate2(num2: Int, num1: Int, print: () -> Unit): Int {
     //执行函数
     print()
     return add(num1, num2)
 }
 // 执行结果
 //sum = 5
 //sum2 = 5
 //执行 calculate2
 //sum3 = 5 -->

2. 将函数作为返回值

在这个示例中,createOperation 函数根据传入的字符串返回不同的函数。

//普通函数
fun add(num1: Int, num2: Int): Int {
    return num1 + num2
}
//普通函数
fun multiply(num1: Int, num2: Int): Int {
    return num1 * num2
}
//将函数作为返回值
fun createOperation(operationType: String): (Int, Int) -> Int {
    return when (operationType) {
        "add" -> ::add
        "multiply" -> ::multiply
        else -> { _, _ -> 0 }
    }
}
fun main() {
    //定义高阶函数:返回值为函数
    val addOperation = createOperation("add")
    val multiplyOperation = createOperation("multiply")
    val multiplyOperation2 = createOperation("multiply2")
    val sum4 = addOperation(5, 3)
    val product = multiplyOperation(5, 3)
    val product2 = multiplyOperation2(5, 3)
    println("sum4: $sum4")
    println("Product: $product")
    println("Product2: $product2")
}
//输出结果
//sum4: 8
//Product: 15
//Product2: 0

3. 函数入参定义为扩展函数

在函数类型的前面加上 className. 表示将函数定义在某个类中即类的扩展函数,使lambda表达式中持有该类的上下文:如 StringBuilder.() 类似 apply 函数

//在函数类型的前面加上 className. 表示将函数定义在某个类中即类的扩展函数,
// 使lambda表达式中持有该类的上下文:如 StringBuilder.()
fun StringBuilder.build(block: StringBuilder.()->Unit):StringBuilder{
    block()
    return this
}
//定义一个扩展函数,用于对String进行操作
fun String.toUpperCaseWithExclamation(): String = this.toUpperCase() + "!"

//定义一个顶层函数使其接受 String扩展函数 ,并返回扩展函数应用后的结果
fun test(block: String.() -> String): String {
    // 假设我们有一个String实例
    val str = "hello"
    // 调用传入的扩展函数,并将str作为接收者
    return str.block()
}

fun main() {
    //高阶函数:入参函数作为某个类的扩展函数如:StringBuilder.()
    var list = listOf("Apple","Orange","Pear","Grape")
    var sb= StringBuilder()
    sb.build {
        append("高阶函数,StringBuilder.() 在lambda 主体中默认持有 StringBuilder 的上下文")
        list.forEach {
            append(" $it ,")
        }
    }
    println("sb 内容 = ${sb.toString()}")
    //使用顶层方法 入参String的扩展函数,lambda 表达式中默认持有String 的引用,所以可以直接调用 String 的扩展函数
    var ss = test {
        toUpperCaseWithExclamation()
    }
    println("ss 内容 = ${ss.toString()}")
}
//打印结果
sb 内容 = 高阶函数,StringBuilder.() 在lambda 主体中默认持有 StringBuilder 的上下文 Apple , Orange , Pear , Grape ,
length = 5
ss 内容 = HELLO!