Kotlin—函数式编程 (一)

今天开始学习Kotlin的第二大思想,函数式编程。

函数式编程在中一切都是函数。

核心概念:

  1. 函数和其它数据类型是一样的,可以作为其它函数的参数传入,也可做为函数的返回值。
  2. 使用表达式,不用语句。
  3. 高阶函数:一个函数可做为另一个函数的参数和返回值
  4. 无副作用:函数执行过程会返回一个结果,不会修改外部变量

高阶函数

函数式编程的关键是支持高阶函数,就是说一个函数可以做为另一个函数参数或者返回值。

函数类型

先看一下什么是函数类型,在Kotlin中每个函数都有一个类型,称为函数类型,函数类型是中数据类型

fun main(args: Array<String>) {
    var a: (Int, Int) -> Int = ::add  
    println(a(1, 2))
}

fun add(a: Int, b: Int): Int {
    return a + b
}

第三行中的 (Int, Int) -> Int 就是函数类型,意思声明一个属性类型为函数类型。

(Int, Int) 说明这个函数要满足,两个Int参数  -> Int 是指返回值是Int类型。

(参数:参数类型)->返回值类型  参数可以有多个,也可以没有就省略。

fun main(args: Array<String>) {
    var a: () -> Unit = ::test
    println(a())

}


fun test() {
    println("无返回值的函数")
}

这是无返回值的函数,如果,不学返回值默认为无返回值。

函数字面量

函数类型可以声明的变量就是函数字面量

函数字面量可以接收三种类型的数据类型。

  • 函数的引用
  • 匿名函数
  • Lambda表达式
fun main(args: Array<String>) {
    var a = ::add             //函数的引用
    var b = ::sub             //函数的引用
    println(a(1, 1))  
    println(b(2, 1))
    println(ride(1, 10))      //匿名函数
    println(divide(10, 1))    //Lambda表达式
}

fun add(a: Int, b: Int): Int {
    return a + b
}

fun sub(a: Int, b: Int): Int {
    return a - b
}

var ride = fun(a: Int, b: Int): Int {
    return a * b
}
var divide = { a: Int, b: Int -> a / b }

函数返回值

把一个函数做另一个函数的返回值使用,这个函数就是高阶函数。

fun main(args: Array<String>) {

    val getfun = getfun("add")
    println(getfun(1, 2))
}

fun getfun(string: String): (Int, Int) -> Int {
    var a: (Int, Int) -> Int
    when (string) {
        "add" -> a = ::add
        else -> {
            a = ::sum
        }
    }

    return a
}

fun add(a: Int, b: Int): Int {
    return a + b
}

fun sum(a: Int, b: Int): Int {
    return a + b
}

函数参数

fun main(args: Array<String>) {

    setFun(add(1, 2))
}

fun setFun(funName: (Int, Int) -> Int) {
    println(funName)
}

fun add(a: Int, b: Int): (Int, Int) -> Int {
    return fun(a: Int, b: Int): Int {
        return a + b
    }
}

Lambda表达式

Lambda表达式是一种匿名函数,它可以做表达式、函数、参数和返回值用

刚才的案例可以改为Lambda表达式用

fun main(args: Array<String>) {

    setFun({ a, b -> a + b })
}

fun setFun(funName: (Int, Int) -> Int) {
    println(funName)
}

fun add(a: Int, b: Int): (Int, Int) -> Int {
    return { a, b -> a + b }
}

Lambda  怎么写

{参数列表:参数类型->Lambda体}

或者在简写{参数列表->Lambda体}

不写参数类型,因为有时候可以自动推到类型Lambda

尾随Lambda

fun main(args: Array<String>) {

    setFun() { a, b -> a + b }
}

fun setFun(funName: (Int, Int) -> Int) {
    println(funName(1, 2))
}

如果函数最后一个是Lambda的时候就可以放到小括号外面

省略参数声明

fun main(args: Array<String>) {
    getString("abc", { it.reversed() })

}

fun getString(s: String, funName: (String) -> String) {
    println(funName(s))
}

Lambda中的return语句

在Lambda直接使用return会使函数直接退出,而不是退出Lambda表达式。

fun main(args: Array<String>) {
    getString("aaAbbb")
}

fun getString(s: String) {
    s.forEach {
        println(it)
        if (it == 'A') {
            return
        }
        println("Lambda")
    }
    println("函数退出")
}

没有打印出 函数退出,证明它直接结束了函数,而非Lambda表达式。

我们用之前学的知识改一下

fun main(args: Array<String>) {
    getString("aaAbbb")
}

fun getString(s: String) {
    forEach@ s.forEach {
        println(it)
        if (it == 'A') {
            return@forEach
        }
        println("Lambda")
    }
    println("函数退出")
}

结果:

这次看到了,说明是结束的Lambda表达式

闭包与捕获变量

闭包使一种特殊的函数,它可以访问函数体之外的变量

fun main(args: Array<String>) {
    val test = test()
    println(test(10))
    println(test(10))
    println(test(10))
}

fun test(): (Int) -> Int {
    var vaule = 10

    fun add(a: Int): Int {
        vaule += a
        return vaule
    }
    return ::add
}

结果:

可以看到,结果是累加了,这就是闭包捕获变量。这些变量会被保存到一个特殊的容器中,即使超过作用域在闭包体中也可以访问到。

内联函数

待补充

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光临天下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值