Lambda编程简介

Android  Kotlin  2024年9月26日 am9:01发布3周前更新 91es.com站长
65 0 0

前言

简单记录一下Lambda编程相关知识,方便自己查阅和学习。

这里重点是理解lambda作为函数参数的使用。

正文

Lambda表达式

Lambda表达式就是一个匿名函数,它是函数式编程的基础,所谓函数式编程实际上就是一种编程范式,即如何编写程序的方法论。函数式编程的思想是将计算机运算视为函数的计算,并且计算的函数可以接收函数作为输入参数或者当作返回值来使用。

使用函数式编程可以减少代码的重复,提高程序的开发效率。

Lambda表达式相对于普通函数有些区别,普通函数有4种返回值类型,即无参数无返回值、无参数有返回值、有参数无返回值、有参数有返回值。

而Lambda表达式只有两种返回值类型,即无参数有返回值、有参数有返回值。

无参数有返回值

在定义无参数有返回值的Lambda表达式时,只需要将函数体写在“{}”中,函数体可以是表达式或语句块。

语法格式如下:

{ 函数体 }

比如

{println()}

那如何调用呢?

在调用Lambda表达式时,只是在Lambda表达式后添加了“()”,“()”就代表了调用该表达式。

语法格式如下:

{函数体}()

比如

{println()}()
有参数有返回值

在定义有参数有返回值的Lambda表达式时,需要指定参数名称以及参数类型,参数之间使用英文“,”分隔。

Lambda表达式中的“->”用于表示箭头,用于指定参数或数据的指向,具体语法格式如下:

//一个参数
{参数名:参数类型-> 函数体 }
//两个参数
{参数名:参数类型,参数名2:参数类型-> 函数体 }

调用时,跟无参的一样,后面添加(),但这里需要传入参数值

{参数名:参数类型,参数名2:参数类型-> 函数体 }(参数值1,参数值2)

定义了一个函数,并将该函数赋值给变量sum,

//计算3+4的结果
var sum = { a:Int, b:Int -> a+b }(3,4)

//或者
//sumFun是一个函数
var sumFun = { a:Int, b:Int -> a+b }
sumFun(3,4)
Lambda表达式返回值

Lambda表达式所表示的函数都是有返回值的,而且不管方法体里面的语句执行多少条,返回值的类型和返回值都是由方法体中最后一条语句决定的。

返回值看最后以后得结果。

var sum = {
            a: Int, b: Int ->
            100
          }(1,2)
Log.d(TAG, "test: $sum ")

返回值为

test: 100

高阶函数的使用

Lambda表达式还可以作为函数的实际参数或者返回值存在,而这种声明,在Kotlin中叫做高阶函数。

将Lambda表达式作为参数或返回值,会大大地简化程序开发时的代码,提高程序开发效率。

函数作为参数使用

Lambda表达式,除了定义在方法的内部,还可以作为函数的实参,这种做法拓宽了我们的编程思维。

下面举例来说

定义
private fun IntRange.pickNumber(condition: (Int) -> Boolean): List<Int> {
    val resultList = mutableListOf<Int>()
    for (i in this) {
        if (condition(i)) {
            resultList.add(i)
        }
    }
    return resultList
}

这里是对IntRange方法的扩展。

  1. 函数名:pickNumber

  2. 参数:condition: (Int) -> Boolean

  3. 返回值类型:List<Int>

重点,参数是[Lambda表达式当作参数传递],因此重点讲这个。

condition: (Int) -> Boolean
  1. condition:形式参数名,可以是改为其他合法的名字。

  2. (Int) -> Boolean:形式参数类型。这里是一个函数类型,函数的参数是Int类型,函数的返回值是Boolean类型。

搞懂上面的意思就很容易明白pickNumber函数的功能。

调用
var list = 1..20
var newList = list.pickNumber({ x: Int -> x % 2 == 0 })
Log.d(TAG, "test: $newList")

输出的结果

test: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
函数作为参数优化

当Lambda表达式作为函数参数使用时,还有3种优化形式,这3种优化形式分别是省略小括号、将参数移动到小括号外面、使用it关键字。

省略小括号

如果函数只有一个参数,且这个参数类型是一个函数类型,则在调用函数时可以去掉函数名称后面的小括号。

这个就是上面我

var list = 1..20
var newList1 = list.pickNumber({ x: Int -> x % 2 == 0 })
Log.d(TAG, "test: $newList1")
//等同上面,可以省略()
var newList2 = list.pickNumber { x: Int -> x % 2 == 0 }
Log.d(TAG, "test: $newList2")
将参数移动到小括号外面

如果一个函数有多个参数,但是最后一个参数类型是函数类型,那么在调用函数时,可以将最后一个参数从括号中移出,并且去掉参数之间的符号“,”。

private fun IntRange.pickNumber(ignoreNumber: Int, condition: (Int) -> Boolean): List<Int> {
    val resultList = mutableListOf<Int>()
    for (i in this) {
        if (ignoreNumber != i && condition(i)) {
            resultList.add(i)
        }
    }
    return resultList
}

调用

var list = 1..20
var newList1 = list.pickNumber(10, { x: Int -> x % 2 == 0 })
Log.d(TAG, "test: $newList1")
//等同上面
var newList2 = list.pickNumber(10) { x: Int -> x % 2 == 0 }
Log.d(TAG, "test: $newList2")

输出的结果一样,少了10

test: [2, 4, 6, 8, 12, 14, 16, 18, 20]

第二个就是把函数体移到()之外。

使用it关键字

无论函数包含多少个参数,如果其中有参数是函数类型,并且函数类型满足只接收一个参数的要求,可以用it关键字代替函数的形参以及箭头。

var list = 1..20
var newList1 = list.pickNumber(10) { x: Int -> x % 2 == 0 }
Log.d(TAG, "test: $newList1")
var newList2 = list.pickNumber(10) { it % 2 == 0 }
Log.d(TAG, "test: $newList2")

函数作为返回值

函数不仅可以作为参数使用,还可以作为返回值使用。

//声明枚举,定义两种类型
private enum class USER {
    NORMAL, VIP
}
// 声明价钱方法
private fun getPrice(userType: USER): (Double) -> Double {
    //判断类型,是否需要打折
    if (userType == USER.NORMAL) {
        return { it }
    }
    return { price -> 0.88 * price }
}

调用

var price1 = getPrice(USER.NORMAL)(100.0)
var price2 = getPrice(USER.VIP)(100.0)
Log.d(TAG, "test price1 : $price1")
Log.d(TAG, "test price2 : $price2")

返回值

test price1 : 100.0
test price2 : 88.0

参考文章

  1. 《Kotlin从基础到实战》

 历史上的今天

  1. 2021: 洛夫:众荷喧哗(0条评论)
  2. 2021: 舒婷:北戴河之滨(0条评论)
  3. 2020: Android硬件加速(0条评论)
  4. 2019: 林清玄:再加两个苹果(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

脚本 adb push apk 新版本

前言这个版本包括创建对应目录等,比之前写的更简单了。这个是同事写的哈哈哈,摘抄于此。正文@echo offecho push update apkif exist null (del null):start@adb devices | findstr "\<device\...

MediaPlayer异常

前言播放媒体测试时,出现Mediaplayer报异常问题,如下打印日志MediaPlayerNative(13594): start called in state 4, mPlayer(0x75b4e81280)MediaPlayerNative(13594): error (-38, 0...

[摘]UML类图符号的各种关系说明

本文摘抄于UML类图符号 各种关系说明以及举例,其实我一直在看UML内容,但有时候总是忘记,因此摘抄于此,谢谢原文作者无私分享UML中描述对象和类之间相互关系的方式包括:依赖,关联,聚合,组合,泛化,实现等。表示关系的强弱关系组合>聚合>关联>依赖相互间关系聚合是表明对...

[代码片]属性动画之无限旋转

前言简单记录一下而已,正文private ObjectAnimator mRotation = null;mRotation = ObjectAnimator.ofFloat(view, "rotation", 0, 360);mRotation.setDuration(2000);//...

[摘]adb 查看系统设置参数

获取系统默认输入法adb shell settings get secure default_input_method更改默认输入法(改为com.sohu.inputmethod.sogouoem/.SogouIME)adb shell settings put secure default_...

手动更新wordpress版本

由于某些原因,WordPress 下载的网站无法打开,导致更新一直失败,因此只好手动更新。一:最新版本WordPress5.3.2中文版:https://downloads.wordpress.org/release/zh_CN/wordpress-5.3.2.zip二、手动更新在服务器里删...