您的位置:首页 > 其它

5、Kotlin的lambda表达式

2020-06-29 05:02 83 查看

Lambda表达式,在kotlin中,使用范围非常广。高阶函数、内联函数、委托属性等方式都要基于对lambda的理解。kotlin的lambda与java一脉相承,却不尽相同。

1、lambda表达式概念

lambda表达式在kotlin中是可以理解是一个可以复用的代码块。可以被其他的函数调用。

2、lambda代码书写

一个Lambda表达式把一小段行为进行编码,你能把它 当做值到处传递,它可以被 独立地声明并存储到一个变量中,但是最常见的还是直接声明它并传递给函数,Lambda表达式的语法,->前为 参数,后为 函数体,始终用 花括号包围。

{ a: Int, b: Int -> a + b }

如果,这个lambda表达式作为实参传递的时候,数据类型是可以推导出来的,我们可以进一步的简化

{ a, b -> a + b }

当然lambda表达式也可以写成多行,例如:

{ a: Int, b: Int ->
print("advancedfun")
val x = a + b ;
a - x ;}

3、lambda的作用域

lambda只作用于调用的函数中,并且也可以获得函数的参数,可以改变函数体内lambda表达式之前的局部变量,和函数所在类的成员变量,当然也可以改变所在类对象的成员变量。如下所示:

fun testAdvancedfun(args: Array<String>, c: Int) {
var d = 1;
advancedfun { a: Int, b: Int ->
print("advancedfun")
d++
val x = a + b + c + d;
a - x;
}
print("$d")
}

注:这边有个非常不一样的一点,java在使用lambda的时候,lambda表示的内部类,java只允许使用final的局部变量。但是kotlin是不用的,kotlin很好的规避了这一点,我们看一下java编译的代码:

public static final void testAdvancedfun(@NotNull String[] args, final int c) {
Intrinsics.checkParameterIsNotNull(args, "args");
final IntRef d = new IntRef();
d.element = 1;
advancedfun((Function2)(new Function2() {
// $FF: synthetic method
// $FF: bridge method
public Object invoke(Object var1, Object var2) {
return this.invoke(((Number)var1).intValue(), ((Number)var2).intValue());
}

public final int invoke(int a, int b) {
TestKt.print("advancedfun");
int var10001 = d.element++;
int x = a + b + c + d.element;
return a - x;
}
}));
print(String.valueOf(d.element));
}

他通过一个Final的IntRef做为载体,很好的规避了此问题,当然这也是我们在Java中规避的策略(1、使用成员变量定义 2、使用一个包装类 3、创建单元素的数组)

4、lambda引用的概念

lambda函数是可以赋值和获取引用的,如下:

fun testAdvancedfun2(args: Array<String>, c: Int) {
fun testFun(i: Int, i1: Int) = { a: Int, b: Int -> a * b };// 赋值到函数testFun
var testFunRef = ::testFun;                              // 获取testFun函数的引用
}

当然,我们也可以把这个函数的引用进行传递,如下

fun advancedfun2(operation: KFunction2<@ParameterName(name = "i") Int, @ParameterName(name = "i1") Int, (Int, Int) -> Int>) {
val result = operation(2, 3)
println("The result is $result")
}

fun testAdvancedfun2(args: Array<String>, c: Int) {
fun testFun(i: Int, i1: Int) = { a: Int, b: Int -> a * b };
var testFunRef = ::testFun;
advancedfun2(testFunRef);
}

也就是说函数的引用类型叫KFunction,有几个参数就是KFunctionX,这其实在java里就是方法的反射。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: