2.3.6 Lambda是语法糖
提到Lambda表达式,也许你听过Lambda演算。其实这是这是两个不同的概念,Lambda演算和图灵机一样,是一种支持理论上完备的形式系统,也是立即函数式编程的理论基础。古老的listp语言就是基于Lambda演算系统而来的,在Listp中,匿名函数是重要的组成部分,它也被叫做Lambda表达式,这就是Lambda表达式名字的由来。所以,相比较Lambda演算而言,Lambda表达式是更加简单的概念。你可以把它理解成简化表达式后的匿名函数,实质上它就是一种语法糖。
我们先来分析下代码清单2-2中的fiterCountries方法的匿名函数,会发现:
1 fun(country:Country)显得比较啰嗦,因为编译器会推导类型,所以只需要一个表达变量的country就行了;
2 return关键字也可以省略,这里返回的是一个有值的表达式;
3 模仿函数类的语法,我们可以用->把参数和返回值连接在一起。
因此,简化后的表达式就变成了这个样子:
contryApp.filterCountries(countries,
{country-> country.continient =="EU" && country.population >10000 })
是不是非常简洁?这个就是Lambda表达式,它与匿名函数一样,是一种函数字面量。我们再来讲解下Lambda具体的语法。现在用Lambda的形式来定义一个加法操作:
val sun :(Int,Int) ->Int ={x,y->x+y} 或者. val sum1 ={x:Int,y:Int -> x+y}
现在来总结下Lambda的语法:
1. 一个Lambda表达式必须通过{}来包裹;
2. 如果Lambda声明了参数部分的类型,且返回值类型支持类型推导,那么Lambda变量就可以省略函数类型声明;
3. 如果Lambda变量声明了函数类型,那么Lanbda的参数部分的类型就可以省略。
此外,如果Lambda表达式返回的不是Unit,那么默认最后一行表达式的值的类型就是返回值类型如:
val foo ={ x:Int ->
val y = x+1
y // 返回值是 y
}
>>> foo(1)
2
Lambda看起来似乎很简单。那么再考虑一个场景,如果用fun关键字来声明Lambda表达式又会怎么样?如代码清单2-3所示。
------------------- 2-3
fun foo1(int:Int){
Log.i("book", int.toString())
}
listOf(1,2,3).forEach {foo1(it)}//对一个整数列表的元素遍历调用foo1,猜猜结果是
-------------------