高阶函数 就是可以接受函数作为参数或者将函数作为返回值的函数。Kotlin 中函数被当做普通数据类型(函数类型),可以做变量,参数,返回值。可以通过 lambda 表达式或者函数方法引用来实现。
函数类型(function type)的定义格式如下:
1 (type1,type2) -> ReturnType
Define And Use 在函数参数类型,以及返回值处定义函数式类型的参数或返回值,这个函数就是高阶函数,大致上分为三类来实现定义高阶函数:
lamda
匿名函数,就是之前的 Local 函数
方法引用,直接引用以及申明了的函数
kotlin 中的类型可以被实现处推断出来,所以变量的类型可以被赋值的时候推断出来,函数的返回值也从被函数的返回值推断出来。
1 2 3 4 5 6 7 val lambda1: (Int) -> Boolean = { it > 2 } val lambda2 = { x: Int -> x > 2 } val anonymous1 = fun(x: Int): Boolean { return x > 2 } val anonymous2 = fun(x: Int) = x > 2 val functionReference = String::filter
调用高阶函数的方式跟调用普通函数类似
1 2 lambda1(1 ) lambda2.invoke(1 )
Bummock 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 @NotNull private static final Function1 lambda1;@NotNull private static final Function1 anonymous1;@NotNull private static final KFunction functionReference;@NotNull public static final Function1 getLambda1 () { return lambda1; } @NotNull public static final Function1 getAnonymous1 () { return anonymous1; } @NotNull public static final KFunction getFunctionReference () { return functionReference; } public static final void main () { lambda1.invoke(1 ); anonymous1.invoke(1 ); ((Function2)functionReference).invoke("" , null .INSTANCE); } public static void main (String[] var0) { main(); } static { lambda1 = (Function1)null .INSTANCE; anonymous1 = (Function1)null .INSTANCE; functionReference = null .INSTANCE; }
在main()
函数调用处可以看见,lambda 、匿名函数以及方法引用都被编译成了Function1
接口类型的实例对象了,所以才能通过invoke()
方法调用高阶函数。在package kotlin.jvm.functions
下,kotlin 替换了多至22个参数的FunctionN
类型。所以在Java 中可以通过实现这些类来调用 Kotlin 中定义的高阶函数(本来 Kotlin 的编译器编译成 Java 代码后也是这样实现的),或者在Java 8 中通过Lambda 表达式来调用。
1 2 3 4 5 6 package kotlin.jvm.functionspublic interface Function1<in P1, out R> : Function<R> { public operator fun invoke (p1: P1) : R }
如果高阶函数是not capturing
的时候,是会存在一定的开销的,可以使用inline
关键字避免
other 多个的 multitude
Function types can be instantiated in a multitude of ways
参考 Idiomatic Kotlin: High-Order functions and Function types