Better

业精于勤荒于嬉

Idiomatic Kotlin: High-order functions and function types

Better's Avatar 2019-06-21 Kotlin

  1. 1. Define And Use
  2. 2. Bummock
  3. 3. other
  4. 4. 参考

高阶函数就是可以接受函数作为参数或者将函数作为返回值的函数。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);
}

// $FF: synthetic method
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.functions
/** A function that takes 1 argument. */
public interface Function1<in P1, out R> : Function<R> {
/** Invokes the function with the specified argument. */
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

This article was last updated on days ago, and the information described in the article may have changed.