Kotlin与Lamda的完美结合

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,999评论 4 368
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,102评论 1 302
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,709评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,439评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,846评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,881评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,062评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,783评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,517评论 1 248
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,762评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,241评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,568评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,236评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,145评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,941评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,965评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,802评论 2 275