转向Kotlin——高阶函数与Lambda表达式

在调用高阶函数时使用Lambda表达式,可以使调用语法更加简洁,不过要想使用这种调用方式,就需要深入了解Lambda表达式的用法。

高阶函数

高阶函数是一种特殊的函数:它接受函数作为参数,或者返回一个函数。

先看一个例子:

    fun progress(param: (name: String) -> String) {
        var result = param("hello ")
        Log.e("jia", "" + result)
    }

progress就是一个高阶函数,它接收一个函数作为自己的参数,声明形参名为param。而且这个参数传入一个String类型的name,返回一个String值。在progress函数体中可以使用该函数。

看下如何使用:

fun normalFun(name: String): String {
    return name + "北京"
}

progress(::normalFun)

将函数作为参数值传入高阶函数,需要再函数名前加两个冒号(::)作为标记。当然也可以采用Lambda表达式,如下:

progress({ name -> name + "上海" })

Lambda表达式和匿名函数

Lambda表达式,或者称为匿名函数,是一种“函数字面值”,也就是一个没有声明的函数,但是可以作为表达式传递出去。

progress({ name -> name + "上海" })

progress是一个高阶函数,它接收一个函数作为参数。参数是一个表达式,本身又是一个函数,也就是说,它是一个函数字面量。

函数类型

对于接受另一个函数作为自己参数的函数,我们必须针对这个参数指定一个函数类型,例如上方提到的progress函数,参数param的类型是 (name: String) -> String 。在函数progress内部,param作为一个函数使用,并传递给param一个String参数。

Lambda表达式语法

Lambda表达式的完整语法形式,也就是函数类型的字面值。

var sum1 = { x: Int, y: Int -> { x + y } }

Lambda表达式包含在大括号内,在完整的语法形式中,参数声明在小括号内,参数类型的声明可选,函数体在“->”符号之后。如果Lambda表达式自动推断的返回值类型不是Unit,那么在Lambda表达式函数体中,最后一条(或者是唯一一条)表达式会被当做整个Lambda表达式的返回值。

如果把可以去掉的部分全部省略,可以写成这样:

var sum2: (Int, Int) -> Int = { x, y -> x + y }

匿名函数

上面讲到的Lambda表达式语法,还有一点没有说明,就是可以指定函数返回值类型。大多数情况下,不需要指定函数类型,因为可以自动推断出。但是,需要明确指定返回值类型,就可以选择另一种语法——匿名函数。

fun(item) = item > 0

匿名函数看起来和通常的函数声明很相似,区别在于省略了函数名。函数体可以是一条表达式,也可以是多条语句。

调用例如:

ints.filter(fun(item) = item > 0)

闭包

Lambda表达式、匿名函数可以访问它的闭包,也就是定义在外层范围中的变量。与Java不同,闭包中捕获的变量是可以修改的,而在Java中必须用final声明。

 var sun = 0
        ints.filter(fun(item) = item > 0).forEach {
            sun += it
        }

总结

高阶函数和Lambda表达式听起来似乎很“高端”,其实它们在使用上并没有多么复杂,尤其是Lambda表达式,许多高级语言都支持。慢慢熟悉吧。

更多内容,欢迎关注我的微信公众号——Android机动车

转向Kotlin——高阶函数与Lambda表达式_第1张图片

你可能感兴趣的:(Kotlin)