IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 【Kotlin】Kotlin的高阶函数与Lambda表达式 -> 正文阅读

[移动开发]【Kotlin】Kotlin的高阶函数与Lambda表达式

前言

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{
  	@Override
  	public 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实例化赋值给d
 
 a(d) //正确写法,d已经是函数对象。

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

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

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

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

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

 //正确写法。调用a函数,传递一个匿名函数进去。
 a(fun(arg:Int):String{
    return arg.toString()
  })
  
  //将匿名函数赋值给d
 val 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表达式是匿名函数的简化形式。完整语法如下:

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

将上文示例中的setOnClickListener传递的匿名函数进行简化,写成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表达式赋值给一个变量时,不能省略参数类型,示例:

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

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

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

五、总结

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

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章           查看所有文章
加:2021-10-26 12:19:17  更:2021-10-26 12:21:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:29:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码