1.基础
Lambda表达式本质还是一个匿名函数,因为其底层还是通过匿名函数来实现的。它是函数式编程的基础,所谓函数式编程实际上就是一种编程范式,即如何编写程序的方法论。
上面这两句话的前半部分你肯定能看懂,但是后半句话貌似会让你有点似懂非懂,那是因为基础还没打好,等基础打好以后再来看后半句话你自然就懂了。
1.1 Lamda表达式最直白、最基础的用法
fun main() {
{ println("hello Lamda") }()//注意这里的小括号
}
上面这段代码运行结果是打印字符串“hello Lamda”,我第一次看到这种写法的时候也是一脸懵逼,没有方法名,没有返回类型,这是什么鬼?然后查了一下它的解释:这是一个lamda表达式也叫匿名函数。嚓,果然是一个连函数名字都没有的小可怜。
但是现在我有一个疑问:“按照你的写法,程序运行的时候lamda表达式也会执行,但是我不想让他总是执行,我想定义一个lamda表达式等我需要用到他的时候再执行,这要怎么搞?”
学而又思 则牛逼,那接下来就看看怎么办。
fun main() { //标记1
公司招聘()
}
var 公司招聘 = { //标记2
var person = 招Kotlin工程师()
println("找到了一个Android开发工程师他的个人信息是:${person.toString()}")
}
fun 招Kotlin工程师(): Person { //标记3
var p = Person("Jowney", 18)
return p
}
这代码看着是不是有点虎逼【手动捂脸】,不过你都开始学Lamda了,我相信Kotlin基础语法,封装、继承、多态什么的应该都有了解了,所以这段代码对你应该不难理解。这也是kotlin比较爽的地方,变量名字可以用汉字,方法定义也不用依托于类。
看上面标记2处的代码,你说这是个啥东西,这就是Lamda表达式,说白了它就是需要你按照一定规则在{ }内来写你的逻辑代码,然后把{ }直接复制给一个变量var/val,然后你就可以向使用方法一样使用这个变量。如果没有赋值给变量的话怎么使用{ }中的代码嘞?很简单就像前面的样例中那样 {逻辑代码 }( )
下面总结一下在{ }内写代码的规则。
1. 无参数的情况 :
val/var 变量名 = { 操作的代码 }
2. 有参数的情况
val/var 变量名 = { 参数1 : 参数类型,参数2 :参数 类型, ... -> 操作参数的代码 }
第一种无参数类型还比较好理解,但是第二种有参数的看着就有点复杂了。来吧举个例子,有助于理解。
fun main() {
var sum = { a: Int, b: Int -> a + b }
var result = sum(2, 3)
println(result)
}
因为我们在写代码的时候不可能不传递参数,所以这个规则就是方便我们传递参数,{ }内部通过->将参数部分与逻辑代码分割开,->前面是参数,后面是被执行的逻辑代码。将{ }赋值给变量sum,sum就可以当成一个方法来使用。
说到这里你可能会有一个新的疑问,返回值呢?你不是说sum就可以当成一个方法来用吗?我现在也传递参数了,但是没有看到return啊!少年稍安勿躁,再上两个样例。
fun main() {
//计算最小值
var min = { a: Int, b: Int, c: Int ->
var t: Int
t = if (a < b) a else b //kotlin版本的三目运算符
if (t > c) t = c
t //最后一行就是返回值
}
var result = min(2, 3, 1)
println(result) //输出结果1
}
import com.csn.mylibrary.Person
fun main() {
//计算最小值
var min = {
var a = 4
var b = 2
var c = 9
var t: Int
t = if (a < b) a else b
if (t > c) t = c
t //最后一行就是返回值了
}
var result = min()
println(result)//输出结果2
}
发现没有,不管{ }是有参的还是无参的,他里面最后一行都默认作为返回值。
你可能有有疑问了,如果如果最后一行是一个函数呢?
fun main() {
var min = {
var a = 4
var b = 2
var c = 9
var t: Int
t = if (a < b) a else b
if (t > c) t = c
t
println("我顶你个肺")
}
var result = min()
println(result)
}
打印结果:
我顶你个肺
kotlin.Unit
看到没返回了一个Unit
总结: lamda表达式就是按照规则将代码写在{ }内,方便Coder来使用。{ }内部针对有参数和无参数做了区分,如果有参数的话就用->分割,->前面是参数部分,后面是逻辑代码部分。不管{ }内是有参还是无参,最后一行的代码,都将被隐式return
1.2 lamda表达式在函数中的使用
fun main() {
test(3, 4) { a, b ->
var t: Int = if (a > b) a else b
println("方法执行了")
t
}
}
fun test(a: Int, b: Int, function: (a: Int, b: Int) -> Int): Int {
return function(a, b)
}
看样例很好理解,定义的test函数中,最后一个参数的参数类型是(a: Int, b: Int) -> Int,是不是看着很熟悉,就是把lamda表达式{ }中的参数和返回值类型给提出来了,然后在方法体中直接把它作为一个函数使用,这个有点像回调啊!最后在使用test函数的时候再具体实现它,如样例所示,直接在()后面跟{}来实现Lamda表达式。当然你也可以直接在第三个参数的位置直接实现Lamda表达式,但是不推荐,因为那样写确实不好看。
fun main() {
test(3, 4,{
a,b->
var t: Int = if (a > b) a else b
println("方法执行了")
t
})
}
fun test(a: Int, b: Int, function: (a: Int, b: Int) -> Int): Int {
return function(a, b)
}
2.Kotlin进阶
看完基础篇是不是觉得Lamda表达式太简单了,没啥好学的【手动捂脸】,骚年!看完进阶篇再嘚瑟也不迟。
2.1 it
先看样例,是不是直接懵逼,这个it是什么鬼,Lamda表达式中的参数呢?test1函数定义Lamda类型参数的时候明明有一个参数的呀!
fun main() {
fun testtt1() = test1(1, 2) {
it*10
}
println(testtt1())
}
fun test1(a: Int, b: Int, function: (a: Int) -> Int): Int {
return function(a+b)
}
哈哈,告诉你吧,这是人家私底下和Kotlin约定好的。
it是在当一个高阶函数中Lambda表达式的参数只有一个的时候可以使用it来使用此参数。it可表示为单个参数的隐式名称,是Kotlin语言约定的。
2.2 下划线
.
在使用Lambda表达式的时候,可以用下划线表示未使用的参数,表示不处理这个参数。
例如在遍历一个Map集合的时候,这当非常有用。
val map = mapOf("key1" to "value1","key2" to "value2","key3" to "value3")
map.forEach{
key , value -> println("$key \t $value")
}
// 不需要key的时候
map.forEach{
_ , value -> println("$value")