转向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机动车(JsAndroidClub)

原文发表时间:2018-09-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏转载gongluck的CSDN博客

前缀、中缀、后缀表达式

它们都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记法。它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前;...

44990
来自专栏Android干货

正则表达式

403100
来自专栏PHP在线

欢迎来到phpdaily

1.Null类型,表示空对象指针,使用typeof检测会返回object。 如果定义的变量在将来用于保存对象,最好将该变量初始化为NUll.可以体现null作为...

33670
来自专栏一“技”之长

Swift中构造方法的解析 原

      构造方法是一个类创建对象最先也是必须调用的方法,在Objective-C中,开发者更习惯称这类方法为初始化方法。在Objective-C中的初始化方...

9720
来自专栏GreenLeaves

C# new关键字和对象类型转换(双括号、is操作符、as操作符)

一、new关键字 CLR要求所有的对象都通过new来创建,代码如下: Object obj=new Object(); 以下是new操作符做的事情 1、计算类型...

22390
来自专栏Java帮帮-微信公众号-技术文章全总结

似懂非懂 Comparable和 Comparator【面试+工作】

在java中提供了两种排序方式:Comparable和 Comparator,它们两个看起来非常的相似,在不是很了解的情况下不知道如何使用,什么情况下使用哪个进...

12330
来自专栏java架构师

实例讲解override和new的区别

一、override:Override关键字主要是提供派生类对基类方法的新实现。 1、不可以用于重写非虚方法和静态方法 2、与其配套使用的关键字是Virtual...

357100
来自专栏Android机器圈

Java中list<Object[]>、list<Student>、list<Map<String,String>>排序

1:list<Object[]>的排序 public static void main(String[] args) { // TODO Auto-gene...

64080
来自专栏开发与安全

从零开始学C++之构造函数与析构函数(三):深拷贝与浅拷贝、空类与空数组

一、深拷贝与浅拷贝 说得简单点,假设一个类有指针成员,如果在拷贝的时候顺带连指针指向的内存也分配了,就称为深拷贝,如下图(v2 从 v 拷贝而来): ? 如果只...

1K00
来自专栏ACM算法日常

基础算法 | 最终章-8 归并排序

我们已经在本系列文章中已经学习了7种算法,其中一种是查找算法,六种是排序算法。本篇文章是基础算法系列的最后一章,我们将学习最后一个排序算法——归并排序。让我们话...

7610

扫码关注云+社区

领取腾讯云代金券