学习Kotlin之高阶函数
定义高阶函数
高阶函数和Lambda的关系是密不可分的。
定义:如果一个函数接收另一个函数作为参数,或者返回值的类型是另一个函数,那么该函数就称为高阶函数。
一个新概念:函数类型。编程语言中有整型、布尔型等字段类型,而Kotlin增加了函数类型。
如何定义,语法规则如下:
(String, Int) -> Unit
->左边是用来声明该函数接收什么参数,多个参数用逗号隔开,如果不接受任何参数,写一对空括号即可;
->右边是用来声明该函数的返回值是什么类型,如果没有返回值就使用Unit,相当于Java中的void。
现在将函数类型添加某个函数的参数声明或者返回值声明上,那么这个函数就是高阶函数了。
fun example(func: (String, Int) -> Unit) { func("hello",123) }
example()函数接收了一个函数类型的参数,它现在是一个高阶函数。调用方法类似于普通函数。
高阶函数的用途
高阶函数允许让函数类型的参数来决定函数的执行逻辑。即使是同一个高阶函数,只要传入不同的函数类型参数,那么它的执行逻辑和最终的返回结果就可能是完全不同的。
例子:
定义一个num1AndNum2()的高阶函数,接收两个整型和一个函数类型的参数。在此函数中对传入的两个整型参数进行某种运算,并返回运算结果,但是具体进行什么运算是由传入的函数类型参数决定的。
新建HigherOrderFunction.kt文件,编写如下代码:
fun num1AndNum2(num1: Int, num2: Int, operation: (Int, Int) -> Int): Int{ val result = operation(num1,num2) return result }
第三个参数是函数类型,它接收两个整型参数并且返回值也是整型的。在num1AndNum2()中我们是看不到具体运算操作的。
具体的运算操作函数还需要继续定义,在HigherOrderFunction.kt文件中添加代码:
fun plus(num1: Int, num2: Int): Int{ return num1 + num2 } fun minus(num1: Int, num2: Int): Int{ return num1 - num2 }
之后我们就可以调用这个高阶函数了:
val num1 = 10 val num2 = 20 val result1 = num1AndNum2(num1, num2, ::plus) println("result1 is $result1")
可以看到传入的第三个参数用了::,这是一种函数引用方法的写法。
以上虽然是实现了高阶函数,但是每次都要定义一个与函数类型参数相匹配的函数,显得过于复杂了。
所以,Kotlin还支持其他方式调用高阶函数,比如Lambda表达式,匿名函数,成员引用等。其中Lambda表达式最常用。
* Lambda表达式实现高阶函数
我们就可以不用写对应的plus函数了:
val result1 = num1AndNum2(num1, num2) { n1, n2 -> n1 + n2 }
Lambda表达式同样可以完整地表达一个函数的参数声明和返回值声明(Lambda表达式中的最后一行代码会自动作为返回值)
高阶函数的原理
Kotlin代码最终都会编译成Java字节码,但Java中并没有高阶函数。这就要归功于Kotlin强大的编译器了。
Kotlin编译器会将高阶函数的语法转换成Java支持的语法结构。比如以上代码:
public static int num1AndNum2(int num1, int num2, Function operation) { int result = (int) operation.invoke(num1, num2); return result; } public static void main() { int num1 = 10; int num2 = 20; int result = num1AndNum2(num1, num2, new Function() { @Override public Integer invoke(Integer n1, Integer n2) { return n1 + n2; } }); }
为了提高可读性,这段代码有些许调整。Function接口是Kotlin内置的一种接口,里面有一个待实现的invoke()函数。
之前的Lambda表达式在里面变成了Function接口的匿名类实现。这就表明,每调用一次Lambda表达式,都会创建一个新的匿名类实例,所以也会造成额外的内存和性能开销。
为了消除这个问题有了内联函数,在下一节中
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)