kotlin高阶函数的初级理解

1.定义

如果一个函数接收另一个函数作为参数,或者返回值的类型是另一个函数,那么该函数就称为高阶函数。
系统中已经有很多,示例:库函数
在 Standard.kt 标准库中提供了一些便捷的内置高阶函数

例如let with run apply also等

例如:
a.let {
  
}

2.看一下简单的使用

fun min(num1: Int, num2: Int): Int {
    return num1 - num2
}

fun plus(num1: Int, num2: Int): Int {
    return num1 + num2
}

// 有的同学可能奇怪以下block参数的写法,是由lambda表达式简化而来,可以重新补充以下lambda表达式的相关知识,接下来会有一些捎带的讲解
fun func1(num1: Int, num2: Int, block: (Int, Int) -> Int): Int {
    return block(num1, num2)
}
fun func2(type: String): (Int, Int) -> Int {
    if (type == "min") {
        return ::min
    } else {
        return ::plus
    }
}

fun main(args: Array<String>) {
    //使用如下
    val result1min = func1(1, 2, ::min)
    val result1plus = func1(1, 2, ::plus)
    println("result1-:$result1min")
    println("result1+:$result1plus")

    val result = func2("min")
    //返回是一个函数,可以调用
    val result2 = result(1, 2)
    println("result2:$result2")

 因为每次都要声明一个方法,很麻烦,可以做以下优化
//    val result3 = func1(1, 2, fun(n1: Int, n2: Int): Int {
//        return n1 + n2
//    })
//    println("result3:result3")
 简化
//    val func2 = func(1, 2, { n1, n2 -> n1 + n2 })

//    val func3 = func1(1, 2) { n1, n2 -> n1 + n2 }

}

3.简单的实际应用

// 当我们求这个列表中最长字符串长度时,可以写出如下代码
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val maxLengthFruit1 = list.maxBy {
    it.length
}

maxBy是kotlin自带的高阶函数方法

让我们一起实现一下maxBy相同功能

fun main(args: Array<String>) {
  
    //这样可以达到一个方法可以多处使用
    //比如一个商品列表,可以检索最长的商品名称,或者最长的生产厂家
    //只需要传入不同的参数函数
    val maxLengthStr = list.maxLength {
        it.length
    }

    //如何简化的
    //因为是传递了一个函数作为参数
    val maxLengthFruit0 = list.maxLength(fun(str: String): Int {
        return str.length
    })
    //首先,我们可以直接将lambda表达式传入maxBy函数当中,因此第一步简化如下所示:
    val maxLengthFruit1 = list.maxLength({ fruit: String -> fruit.length })
    //当Lambda 参数是函数的最后一个参数时,可以将Lambda 表达式移到函数括号的外面
    val maxLengthFruit2 = list.maxLength(){ fruit: String -> fruit.length }
    //如果Lambda 参数是函数的唯一一个参数的话,还可以将函数的括号省略
    val maxLengthFruit3 = list.maxLength{ fruit: String -> fruit.length }
    //由于Kotlin拥有出色的类型推导机制,Lambda 表达式中的参数列表其实在大多数情况下不必声明参数类型
    val maxLengthFruit4 = list.maxLength{ fruit -> fruit.length }
    //当Lambda 表达式的参数列表中只有一个参数时,也不必声明参数名,而是可以使用it关键字来代替
    val maxLengthFruit5 = list.maxLength{
        it.length
    }

    println(maxLengthStr)

    // 由以下简化而来

}

//自定义扩展函数
fun List<String>.maxLength(block: (String) -> Int): String {
    var str = ""
//    val iterator = iterator()
    /**
     * 扩展小知识
     *
     * 如果没有使用Iterator,遍历一个数组的方法是使用索引:
     * for(int i=0; i<array.size(); i++) { ... get(i) ... }
     * 而访问一个链表(LinkedList)又必须使用while循环:
     * while((e=e.next())!=null) { ... e.data() ... }
     * 如果以后需要把ArrayList更换为LinkedList,则原来的客户端代码必须全部重写。
     * 为解决以上问题,Iterator模式总是用同一种逻辑来遍历集合:
     * for(Iterator it = c.iterater(); it.hasNext(); ) { ... }
     * 奥秘在于客户端自身不维护遍历集合的"指针",所有的内部状态(如当前元素位置,是否有下一个元素)
     * 都由Iterator来维护,
     * 而这个Iterator由集合类通过工厂方法生成,因此,它知道如何遍历整个集合。
     * 客户端从不直接和集合类打交道,它总是控制Iterator,
     * 向它发送"向前","向后","取当前元素"的命令,就可以间接遍历整个集合。
     */
    for (fruit in this) {
        if (block(fruit) > str.length) {
            str = fruit
        }
    }
    return str
}

3.1 也可以用作简单的接口回调(多个参数一个函数)

fun show(isShow: Boolean, callback: (String) -> Unit) {
    if (isShow) {
        callback("高阶 show")
    }
}


fun use(){

    //写法一
    show(true, callback = {it->
        println("高阶函数返回结果:$it")
    })
    //写法二
    show(true, {it->
        println("高阶函数返回结果:$it")
    })
    //写法三
    show(true) {
        println("高阶函数返回结果:$it")
    }
}

fun main() {
    use()
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值