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
}

结果:

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

内联函数

待补充

猜你喜欢

转载自blog.csdn.net/qq_41346910/article/details/88822546