自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件
自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件
自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件

前言

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

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

正文

Lambda表达式

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

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

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

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

无参数有返回值

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

语法格式如下:

  1. { 函数体 }
复制

比如

  1. {println()}
复制

那如何调用呢?

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

语法格式如下:

  1. {函数体}()
复制

比如

  1. {println()}()
复制
有参数有返回值

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

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

  1. //一个参数
  2. {参数名:参数类型-> 函数体 }
  3. //两个参数
  4. {参数名:参数类型,参数名2:参数类型-> 函数体 }
复制

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

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

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

  1. //计算3+4的结果
  2. var sum = { a:Int, b:Int -> a+b }(3,4)
  3. //或者
  4. //sumFun是一个函数
  5. var sumFun = { a:Int, b:Int -> a+b }
  6. sumFun(3,4)
复制
Lambda表达式返回值

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

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

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

返回值为

  1. test: 100
复制

高阶函数的使用

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

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

函数作为参数使用

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

下面举例来说

定义
  1. private fun IntRange.pickNumber(condition: (Int) -> Boolean): List<Int> {
  2. val resultList = mutableListOf<Int>()
  3. for (i in this) {
  4. if (condition(i)) {
  5. resultList.add(i)
  6. }
  7. }
  8. return resultList
  9. }
复制

这里是对IntRange方法的扩展。

  1. 函数名:pickNumber

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

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

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

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

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

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

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

输出的结果

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

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

省略小括号

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

这个就是上面我

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

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

  1. private fun IntRange.pickNumber(ignoreNumber: Int, condition: (Int) -> Boolean): List<Int> {
  2. val resultList = mutableListOf<Int>()
  3. for (i in this) {
  4. if (ignoreNumber != i && condition(i)) {
  5. resultList.add(i)
  6. }
  7. }
  8. return resultList
  9. }
复制

调用

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

输出的结果一样,少了10

  1. test: [2, 4, 6, 8, 12, 14, 16, 18, 20]
复制

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

使用it关键字

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

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

函数作为返回值

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

  1. //声明枚举,定义两种类型
  2. private enum class USER {
  3. NORMAL, VIP
  4. }
  5. // 声明价钱方法
  6. private fun getPrice(userType: USER): (Double) -> Double {
  7. //判断类型,是否需要打折
  8. if (userType == USER.NORMAL) {
  9. return { it }
  10. }
  11. return { price -> 0.88 * price }
  12. }
复制

调用

  1. var price1 = getPrice(USER.NORMAL)(100.0)
  2. var price2 = getPrice(USER.VIP)(100.0)
  3. Log.d(TAG, "test price1 : $price1")
  4. Log.d(TAG, "test price2 : $price2")
复制

返回值

  1. test price1 : 100.0
  2. test price2 : 88.0
复制

参考文章

  1. 《Kotlin从基础到实战》

自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件

相关文章

自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件

暂无评论

none
暂无评论...