Java中有匿名函数,java8之后增加了对lambda的支持,但是开发中用基本没用过,所以在切换到Kotlin后被折磨的想死,这次专门来学习一下。
匿名函数
简介
在Java8之前使用回调,需要定义一个接口,并在函数调用时,使用new实例化接口的实现
//接口声明
public interface OnItemClickListner {
void onClick(int position, String name);
}
//声明接口注册函数
public void setOnItemClickListener(OnItemClickListner l) {
mListener = l;
}
//使用回到函数
mListView.setOnItemClickListener(new setOnItemClickListener() {
@Override
public void onCLick(int position, String name) {
//do something
}
});
在kotlin中使用匿名函数,可以直接把处理逻辑的函数传递过去
//完全体,跟java类似
mListView.setOnClickListener(object : OnItemClickListner {
override fun onCLick(int position, String name) {
//do something
}
})
//简化后
mListView.setOnItemClickListener{ position, name ->
//do something
}
//如果position和name用不到可以使用下划线代替
mListView.setOnItemClickListener{ _, _ ->
//do something
}
这样就是匿名函数了。。。刚开始看一脸懵啊,这是调用的什么鬼,咱们从头看看匿名函数的定义
Lambda 表达式与匿名函数
lambda 表达式与匿名函数是“函数字面值”,即未声明的函数, 但立即做为表达式传递。
max(strings, { a, b -> a.length < b.length })
max接受一个函数作为第二个参数,它等同于下面的具名函数
fun compare(a:String, b:String) :Boolean {
a.length < b.length
}
既然函数可以作为参数,那怎么去使用呢
函数作为参数
函数变量入参
我们可以实例化一个函数,作为参数传入调用函数。
例:
//定义匿名函数变量
val performCalc: (Int, Int) -> String = { a, b ->
val sum = a + b
"$sum"
}
//调用其他函数,传入函数变量
printCalcResult(3, 4, performCalc)
fun printCalcResult(a: Int, b: Int, funcp: (Int, Int) -> String) {
println(funcp(a, b))
}
函数作为入参
如果不实例化函数,能不能直接调用呢
printCalcResult(3, 4, { a, b ->
val sum = a + b
"$sum"
})
kotlin中,这个调用还有改动的空间,如果函数参数时最后一个值,可以将匿名函数放在圆括号后面
printCalcResult(3, 4) { a, b ->
val sum = a + b
"$sum"
}
如果只有一个参数,可以直接省略圆括号
printCalcResult{ a, b ->
val sum = a + b
"$sum"
}
具名函数引用
我们可以直接将已声明的函数作为变量传入函数
//具名函数calc
fun calc(a: Int, b: Int): Int {
return a + b
}
fun printCalc(a: Int, b: Int, p: (Int, Int) -> Int) {
//调用具名函数变量p方法
println(p(a, b))
}
printCalc(3, 4, ::calc)
返回值为函数
//返回类型为 () -> Int 的函数
inline fun printCalc(): () -> Int {
//返回一个匿名函数
return {
val a = 3
val b = 4
a + b
}
}
val p = printCalc()
println(p())