Kotlin与Lamda的完美结合

2020-07-15  本文已影响0人  Jowney

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")

上一篇下一篇

猜你喜欢

热点阅读