前言

Kotlin的高阶函数与Lambda表达式是Kotlin的两大特色,使用频率非常高。熟悉它的用法与本质对于简化代码、提升开发效率非常有帮助。
这两个概念不是同一个东西,但是又有非常紧密的关联。这篇文章带你弄懂什么是高阶函数,以及Lambda表达式的本质和使用。

一、什么是高阶函数

高阶函数就是将函数类型用作参数或返回值的函数,例如:

函数类型当作参数

  fun a(arg:(Int)->String):String{arg(1)}

函数类型当作返回值

  fun b(arg:(Int)->String):(Int)->Unit{...}

什么是函数类型

Kotlin 使用类似 (Int) -> String 的一系列函数类型来处理函数的声明。
例如onClick的赋值操作:

val onClick: (View) -> Unit = ……

其中(View) -> Unit就是一种函数类型。

二、在Java里如何将函数当作参数传给另一个函数

在Java里不能将函数当作参数传给另一个函数,但是有一个变通的方案,就是将函数包装成Interface。比如点击事件,将onClick函数包装成OnClickListener传递给View的setOnClickListener函数:

public interface OnClickListener{void onClick(View view)
}OnClickListener onClickListener=new OnClickListener{@Overridepublic void onClick(View view){doSomething();}
}
view.setOnClickListener(onClickListener);

View的源码简化:

public class View{OnClickListener mOnClickListener;public void setOnClickListener(OnClickListener onClickListener){this.mOnClickListener=onClickListener}public void onTouchEvent(MotionEvent motionEvent){...mOnClickListener.onClick(this);...}}

三、在Kotlin里如何将函数当作参数传给另一个函数

先看这两个函数:

   //定义一个参数为函数类型的函数(高阶函数)fun a(arg:(Int)->String):String{arg(1)}//定义一个接受Int返回String的函数fun b(arg:Int):String{return arg.toString()}

如何在调用a的时候将b作为实参传给a呢?首先要将函数b实例化变成对象才能传递。

(1)使用双冒号实例化函数

 a(b)  //错误写法,编译不通过。不能将函数本身直接传递。b没有实例化,不是对象a(::b) //正确写法,将b用双冒号实例化再进行传递val d= ::b  //将b实例化赋值给da(d) //正确写法,d已经是函数对象。

(2)使用匿名函数实例化函数

所谓匿名函数,就是没有名字的函数,比如

fun(arg:Int):String{  //跟正常函数比,没有函数名字return arg.toString()
}

匿名函数不是一个函数类型,它其实是函数实例(对象)。

继续看如何调用上面的高阶函数a:

 //正确写法。调用a函数,传递一个匿名函数进去。a(fun(arg:Int):String{return arg.toString()})//将匿名函数赋值给dval d=fun(arg:Int):String{return arg.toString()}a(d) //正确写法。d已经是匿名函数。

在kotlin里如何定义OnClickListener?

fun setOnClickListener(onClick:(View)->Unit){this.onClick=onClick
}
view.setOnClickListener(fun(v:View)->Unit){doSomething()
})

(3)、使用Lambda表达式实例化函数

view.setOnClickListener{doSomething()
}

四、Lambda表达式

Lambda表达式是匿名函数的简化形式。所以Lamdba表达式跟匿名函数一样,它不是一个函数类型,它是函数实例(对象)。

完整的lambda表达式示例:

 { x: Int, y: Int -> x + y }

其中“->”前面是参数列表,“->”后面是函数实现。

将上文示例中的setOnClickListener传递的匿名函数进行简化,写成Lambda表达式:

//不用lambda表达式,使用传递匿名函数:
view.setOnClickListener(fun(v:View)->Unit){doSomething()
})//使用Lambda表达式的写法:
view.setOnClickListener({v:View->doSomething()
})

Lambda表达式的特点

(1)、如果Lambda是函数的最后一个参数,可以将Lambda写在括号外面:

view.setOnClickListener(){v:View->doSomething()
}

(2)、如果Lambda是函数唯一的参数,还可以将括号去掉:

view.setOnClickListener{v:View->doSomething()
}

(3)、如果Lambda内部只有一个参数,可以省略掉不写:

view.setOnClickListener{doSomething()
}

需要使用这个省略的参数时,用it代表即可。

view.setOnClickListener{doSomething()it.setVibility(View.GONE)
}

(4)、Lambda表达式的返回值不能用return,只能使用最后一行代码表示返回值:

  //编译报错val d :(Int)->String  = {return it.toString()  //编译报错:return is not allowed here}//正确val d :(Int)->String  = {it.toString() }

Lambda参数类型哪些情况下不能省略?

在上面的示例中,可以省略参数类型是因为setOnClickListener函数已经声明了参数类型,Lambda可以从上下文推断出来。而当我们将Lambda表达式赋值给一个变量时,不能省略参数类型,示例:

  //正确,将匿名函数赋值给dval d = fun(arg:Int):String{return arg.toString()}//错误,不能省略参数类型val d = {it.toString() //报错}

在赋值操作时如果一定要省略Lambda表达式类型,必须给左边变量指明类型,示例:

  //正确 ,在左边的变量指明类型val d :(Int)->String  = {it.toString()}

五、总结

在kotlin里,函数与类都是一等公民,函数也可以实例化作为参数传递给另一个函数,函数也可以当作函数的返回值。函数需要实例化变成对象才可以进行传递,使用双冒号、匿名函数、Lambda表达式都可以将函数实例化。

【Kotlin】Kotlin的高阶函数与Lambda表达式相关推荐

  1. Kotlin高阶函数及Lambda表达式实现接口回调

    文章目录 什么是高阶函数? Lambda 表达式 使用Kotlin高阶函数实现接口回调 Java中接口使用 Kotlin中接口使用 什么是高阶函数? 高阶函数是将函数作为参数或者返回值的函数. 特点 ...

  2. Kotlin中的高阶函数

    博客地址sguotao.top/Kotlin-2018- 在Kotlin中,高阶函数是指将一个函数作为另一个函数的参数或者返回值.如果用f(x).g(x)用来表示两个函数,那么高阶函数可以表示为f(g ...

  3. Kotlin基础 9 - 高阶函数

    高阶函数的基本概念 1.传入或者返回函数的函数 2.函数引用 ::println 3.带有Receiver的引用 pdfPrinter:println fun main(args: Array< ...

  4. Android老油条都知道的7个Gradle实用奇技淫巧,kotlin高阶函数和lambda示例

    "com.android.support.test.espresso:espresso-idling-resource:3.0.2" : [ 'com.android.suppor ...

  5. Kotlin 集合类的高阶函数

    集合类:用于存放对象的引用,而非对象本身. 数据结构主要解决三个问题: 数据元素之间的逻辑关系:集合.线性结构.树形结构.图形结构等. 数据的物理结构:顺序.链表.索引.散列表.等形式. 数据的处理运 ...

  6. Kotlin 编程核心基石—高阶函数

    前言 1. 高阶函数有多重要? 高阶函数,在 Kotlin 里有着举足轻重的地位.它是 Kotlin 函数式编程的基石,它是各种框架的关键元素,比如:协程,Jetpack Compose,Gradle ...

  7. 学习Kotlin(五)函数与Lambda表达式

    推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...

  8. Kotlin小知识之高阶函数

    文章目录 高阶函数 定义高阶函数 函数类型 高阶函数示例 内联函数 内联函数的作用 内联函数的用法 noinline与crossinline 高阶函数 定义高阶函数 高阶函数和Lambda的关系是密不 ...

  9. Kotlin——高阶函数详解与标准的高阶函数使用

    一.高阶函数介绍 在介绍高阶函数之前,或许您先应该了解Kotlin中,基础函数的使用与定义.您可以参见Kotlin--初级篇(七):函数(方法)基础使用这边文章的用法. 在Kotlin中,高阶函数即指 ...

最新文章

  1. 2021年逆天Java调优方案出来了!直接省掉一半成本,吹爆!!!
  2. android5.1内核版本,Android-x86现已基于5.1.1 Lollipop:支持UEFI和64位内核
  3. unicode表_Python数据库操作 Mysql数据库表引擎与字符集#学习猿地
  4. dr. unarchiver_P160 四季可穿,数仙女尽折腰!醉高版本Dr马丁靴女2020秋冬新款牛筋底1460英伦风8孔系带复古机车军靴真皮短靴马丁靴...
  5. nginx做正向代理
  6. maven中spring-boot-dependencies变量名冲突
  7. 项目管理理论与实践系列文章索引
  8. 模型压缩:模型量化打怪升级之路-工具篇
  9. amazeui学习笔记二(进阶开发2)--Web组件简介Web Component
  10. CCCC-GPLT L2-020. 功夫传人 团体程序设计天梯赛
  11. Eclipse中如何让Java类与Servlet产生关联【实现处理请求内容】
  12. 2. JavaScript Boolean 对象
  13. 事件mousseenter和mouseover的区别
  14. 微信小程序云开发之初体验(详细教程)
  15. 网线:568A 568B线序
  16. 将源码打包成deb软件包
  17. linux配置dhcp超级作用域,Linux DHCP服务器 超级作用域
  18. echarts地图设置legend_ECharts 的第 100 个版本!
  19. win10如何打开摄像头_win10录屏软件哪个好?可录摄像头不限时长的视频录制方法...
  20. Xposed学习笔记之蚂蚁森林能量自动收取模块

热门文章

  1. secureCRT彩色字体设置
  2. 基于python下django框架 实现多用户商城平台详细设计
  3. 【stm32】引脚高低电平、上拉输入与下拉输入
  4. ATFX:欧元兑土耳其里拉,历史最高价附近持续震荡
  5. 防封号电销系统哪里有?真的防封吗?
  6. Html canvas 五子棋
  7. SAT作文模板是把双刃剑
  8. 如何实现微信自定义分享标题、图片、描述等信息
  9. 成人高考中湖南师范大学录取分数线是
  10. Fomo3D式套利模式再现:“聪明”玩家狠狠地薅了一把羊毛!