《Kotlin从小白到大牛》第14章:函数式编程基石——高阶函数和Lambda表达式

本文详细介绍了Kotlin中的函数式编程基础,重点关注高阶函数和Lambda表达式。从函数式编程的概念出发,阐述了Kotlin如何支持函数成为一等公民,包括函数类型、函数引用、匿名函数以及Lambda表达式的用法。同时,通过实例展示了函数作为参数和返回值的使用,以及Lambda表达式的简化形式,如参数类型推导、尾随Lambda和隐式参数。此外,还探讨了闭包和捕获变量的概念,以及内联函数在提高性能方面的作用。
摘要由CSDN通过智能技术生成

第14章 函数式编程基石——高阶函数和Lambda表达式

函数式编程思想虽然与面向对象一样立即悠久,但是支持函数式编程的计算机语言不过是近几年的事情。这些语言有Swift、Python、Java 8和C++11等,作为新生的语言Kotlin也支持函数式编程。本章将介绍Kotlin语言中函数式编程最重要的基础知识——高阶函数和Lambda表达式。

14.1 函数式编程简介

函数式编程(functional programming)与面向对象编程一样都一种编程范式,函数式编程,也称为面向函数的编程。在函数式编程中一切都是函数。
函数式编程核心概念如下:
o 函数是“一等公民”:是指函数与其他数据类型是一样的,处于平等的地位。函数可以作为其他函数的参数传入,也可以作为其他函数的返回值返回。
o 使用表达式,不用语句:函数式编程关心的输入和输出,即:参数和返回值。在程序中使用表达式可以有返回值,而语句没有。例如:控制结构中的if和when结构都属于表达式。
o 高阶函数:函数式编程支持高阶函数,所谓高阶函数就是一个函数可以作为另外一个函数的参数或返回值。
o 无副作用:是指函数执行过程会返回一个结果,不会修改外部变量,这就是“纯函数”,同样的输入参数一定会有同样的输出结果。
Kotlin语言支持函数式编程,提供了函数类型、高阶函数和Lambda表达式。

14.2 高阶函数

函数式编程的关键是高阶函数的支持。一个函数可以作为另一个函数的参数,或者返回值,那么这个函数就是“高阶函数”。本节介绍一下高阶函数。

14.2.1 函数类型
Kotlin中每一个函数都有一个类型,称为“函数类型”,函数类型作为一种数据类型与数据类型在使用场景没有区别。可以声明变量,也可以作为其他函数的参数或者其他函数的返回值使用。
现有如下3个函数的定义:
//代码文件:chapter14/src/com/a51work6/section2/ch14.2.1.kt
package com.a51work6.section2

//定义计算长方形面积函数
//函数类型(Double, Double) -> Double
fun rectangleArea(width: Double, height: Double): Double { ①

return  width * height    

}

//定义计算三角形面积函数
//函数类型(Double, Double) -> Double
fun triangleArea(bottom: Double, height: Double) = 0.5 * bottom * height ②

fun sayHello() { //函数类型()->Unit ③
print(“Hello, World”)
}

fun main(args: Array) {

val getArea: (Double, Double) ->Double = ::triangleArea ④
//调用函数
val area = getArea(50.0, 40.0)    ⑤
print(area)   //1000.0

}
上述代码中,函数rectangleArea和triangleArea具有相同的函数类型(Double, Double) -> Double。函数类型就是把函数参数列表中的参数类型保留下来,再加上箭头符号和返回类型,形式如下:
参数列表中的参数类型 -> 返回类型
每一个函数都有函数类型,即便是函数列表中没有参数,以及没有返回值的函数也有函数类型,如代码第③行的sayHello()函数,sayHello()函数的函数类型是()->Unit。

14.2.2 函数字面量
函数类型可以声明的变量,那么函数类型变量能够接收什么的数据呢?即函数字面量如何表示的问题,函数字面量可以有三种表示:
函数引用。引用到一个已经定义好的,有名字的函数。它可以作为函数字面量。
匿名函数。没有名字的函数,即匿名函数,它也可以作为函数字面量。
Lambda表达式。Lambda表达式是一种匿名函数,可以作为函数字面量。
示例代码如下:
//代码文件:chapter14/src/com/a51work6/section2/ch14.2.2.kt
package com.a51work6.section2

fun calculate(opr: Char): (Int, Int) -> Int {

//加法函数
fun add(a: Int, b: Int): Int { 
    return a + b
}

//减法函数
fun sub(a: Int, b: Int): Int {
    return a - b
}

val result: (Int, Int) -> Int =
        when (opr) {
            '+' -> ::add                  ①
            '-' -> ::sub                    ②
            '*' -> {
                //乘法匿名函数
                fun(a: Int, b: Int):Int {       ③
                    return (a * b)
                }
            }
            else -> { a, b ->(a / b) } //除法Lambda表达式    ④
        }
return result

}

fun main(args: Array) {
val f1 = calculate(’+’) ⑤
println(f1(10, 5)) //调用f1变量 ⑥
val f2 = calculate(’-’)
println(f2(10, 5))
val f3 = calculate(’*’)
println(f3(10, 5))
val f4 = calculate(’/’)
println(f4(10, 5))
}
上述代码第①行和第②行是函数引用,采用“双冒号加函数名”形式引用,add和sub是两个局部函数,它们的函数引用表示方式是::add和::sub,它们可以作为函数字面量赋值给result变量。代码第③行声明匿名函数,匿名函数不需要函数名,它是一个表达式直接赋值给result变量。代码第④行采用的Lambda表达式,也可以赋值给result变量。
获得一个函数类型的变量之后如何使用呢?答案是可以把它当作函数一样调用。例如代码第⑤行val f1 = calculate(’+’)中f1是一个函数类型变量,事实上f1就是指向add函数的。代码第⑥行是调用f1函数类型变量,事实上就是在调用add函数。其他的变量以此类推,不再赘述。

14.2.3 函数作为另一个函数返回值使用
可以把函数作为另一个函数的返回值使用,那么这个函数属于高阶函数。14.2.2节的calculate函数的返回类型就是(Int, Int) -> Int函数类型,说明calculate是高阶函数。下面再介绍一个函数作为另一个函数返回值使用的示例:
//代码文件:chapter14/src/com/a51work6/section2/ch14.2.3.kt
package com.a51work6.section2

fun getArea(type: String): (Double, Double) -> Double { ①

var returnFunction: (Double, Double)-> Double             ②

when (type) {
    "rect" ->   //rect 表示长方形
        returnFun
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值