高阶函数实现原理 - zhpanvip/AndroidNote GitHub Wiki
一、Kotlin的高阶函数
如果一个函数接收另一个函数作为参数,或者返回值的类型是另一个函数,那么该函数就称为高阶函数。
高阶函数的基本语法:(String,Int)-> Unit
->左边部分用来声明函数接收什么类型的参数,多个参数之间用逗号隔开,如果不接收任何参数,可用括号表示。而->右边部分用于声明该函数的返回类型,没有返回值就使用Unit,相当于void。
举个例子:
fun num1AndNum2(num1: Int, num2: Int, operation: (Int, Int) -> Int): Int {
return operation(num1, num2)
}
上述函数接收两个Int类型的参数,和一个函数类型的参数。这个函数即为一个高阶函数。接下来看如何调用高阶函数。
首先定义两个函数
fun plus(num1: Int, num2: Int): Int {
return num1 + num2
}
fun minus(num1: Int, num2: Int): Int {
return num1 - num2
}
接着讲上述两个函数作为num1AndNum2函数的参数如下:
fun main() {
val num1 = 100
val num2 = 80
val result1 = num1AndNum2(num1, num2, ::plus)
val result2 = num1AndNum2(num1, num2, ::minus)
print("result1 = $result1")
print("result2 = $result2")
}
打印结果:
result1 = 180
result2 = 20
可以看到,想要使用高阶函数需要定义一个与高阶函的数参数匹配的函数作为参数才行,这样写相当麻烦。
其实,kotlin支持 多种方式调用高阶函数,如lambada表达式、匿名函数、成员引用等。其中Lambda表达式是最常见的高阶函数调用方式。上述代码使用Lambda表达式的写法如下:
fun main() {
val num1 = 100
val num2 = 80
val result1 = num1AndNum2(num1, num2) { n1, n2 ->
n1 + n2
}
val result2 = num1AndNum2(num1, num2){ n1, n2 ->
n1 - n2
}
print("result1 = $result1")
print("result2 = $result2")
}
二、高阶函数实现原理
因为kotlin代码最终也是会被编译成字节码的,因此可以将上述高阶函数编译成的字节码,再反编译成java的代码,得到如下结果:
public final int num1AndNum2(int num1, int num2, @NotNull Function2 operation) {
Intrinsics.checkParameterIsNotNull(operation, "operation");
return ((Number)operation.invoke(num1, num2)).intValue();
}
可以看到,将kotlin代码编程java代码后,高阶函数变成了一个 Function2 参数。而这个Function2是kotlin中定义的一个接口:
public interface Function2<in P1, in P2, out R> : Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(p1: P1, p2: P2): R
}
也就是说,kotlin 高阶函数的实现其实使用的是匿名内部类。