【Kotlin -- 知识点】Lambda 表达式

一、Lambda 介绍

Lambda 表达式的本质其实是匿名函数,因为在其底层实现中还是通过匿名函数来实现的。但是我们在用的时候不必关心其底层实现。不过 Lambda 的出现确实是减少了代码量的编写,同时也使代码变得更加简洁明了。 Lambda 作为函数式编程的基础,其语法也是相当简单的。

应用场景:

  • 当一个事件发生的时候运行这个事件处理器
  • 把这个操作应用到这个数据结构中所有的元素上

二、Lambda 使用

2.1 Lambda 表达式的特点

  • Lambda 表达式总是被大括号括着
  • 其参数(如果存在)在符号’->'之前声明(参数类型可以省略)
  • 函数体(如果存在)在符号’->'后面。

2.2 Lambda 语法

  1. 无参数的情况 :
    val/var 变量名 = { 操作的代码 }
  2. 有参数的情况
    val/var 变量名 : (参数的类型,参数类型,…) -> 返回值类型 = {参数1,参数2,… -> 操作参数的代码 }
    可等价于
    //此种写法:即表达式的返回值类型会根据操作的代码自推导出来。
    val/var 变量名 = { 参数1 : 类型,参数2 : 类型, … -> 操作参数的代码 }
  3. lambda表达式作为函数中的参数的时候,这里举一个例子:
    fun test(a : Int, 参数名 : (参数1 : 类型,参数2 : 类型, … ) -> 表达式返回类型){ … }
  • 实例一:无参数的情况
// 源代码
fun test(){ println("无参数") }

// lambda代码
val test = { println("无参数") }

// 调用
test()  => 结果为:无参数
  • 实例二:有参数的情况
// 源代码
fun test(a : Int , b : Int) : Int{    
	return a + b
}

// lambdaval 
test : (Int , Int) -> Int = {a , b -> a + b}

// 或者
val test = {a : Int , b : Int -> a + b}

// 调用
test(3,5) => 结果为:8
  • 实例三:lambda 表达式作为函数中的参数的时候
// 源代码
fun test(a : Int , b : Int) : Int{    
	return a + b
}

fun sum(num1 : Int , num2 : Int) : Int{    
	return num1 + num2
}

// 调用
test(10,sum(3,5)) // 结果为:18

// lambdafun 
test(a : Int , b : (num1 : Int , num2 : Int) -> Int) : Int{    
	return a + b.invoke(3,5)
}

// 调用
test(10,{ num1: Int, num2: Int ->  num1 + num2 })  // 结果为:18

2.3 小结

  1. lambda 表达式总是被大括号括着。

  2. 定义完整的 Lambda 表达式如上面实例中的语法2,它有其完整的参数类型标注,与表达式返回值。当我们把一些类型标注省略的情况下,就如上面实例中的语法2的另外一种类型。当它推断出的返回值类型不为’Unit’时,它的返回值即为->符号后面代码的最后一个(或只有一个)表达式的类型。

  3. 在上面例子中语法3的情况表示为:高阶函数,当Lambda表达式作为其一个参数时,只为其表达式提供了参数类型与返回类型,所以,我们在调用此高阶函数的时候我们要为该Lambda表达式写出它的具体实现。

  4. invoke()函数:表示为通过函数变量调用自身,因为上面例子中的变量 b 是一个匿名函数。

三、Lambda 实践

1. 如何使用 it

  • it 并不是 Kotlin 中的关键字,也不是保留字;
  • it 是在当一个高阶方法中 Lambda 表达式的参数只有一个的时候可以使用 it 来使用该参数;
  • it 可表示为单个参数的隐式名称,是 Kotlin 语言约定的

实例:使用隐形参数 it

fun test(num1 : Int, bool : (Int) -> Boolean) : Int{    
	return if (bool(num1)){ num1 } else 0
}

println(test(10,{it > 5}))

println(test(4,{it > 5}))

输出结果:

10
0

2. 如何使用下划线(_)

在使用 Lambda 表达式的时候,可以用下划线 (_) 表示未使用的参数,表示不处理这个参数。

val map = mapOf("key1" to "value1","key2" to "value2","key3" to "value3")

map.forEach{
     key , value -> println("$key \t $value")
}

// 不需要key的时候
map.forEach{
    _ , value -> println("$value")
}

输出结果:

key1 value1
key2 value2
key3 value3
value1
value2
value3

3. 如何使用匿名函数

  • 匿名函数的特点是可以明确指定其返回值类型。
  • 它和常规函数的定义几乎相似。他们的区别在于,匿名函数没有函数名。
// 当返回值可以自动推断出来的时候,可以省略,和函数一样
val test1 = fun(x : Int , y : Int) = x + y 

val test2 = fun(x : Int , y : Int) : Int = x + y

val test3 = fun(x : Int , y : Int) : Int{    
	return x + y
}

println(test1(3,5))
println(test2(4,6))
println(test3(5,7))

输出结果:

8
10
12

4. 实例

在 Android 开发中为 RecyclerView 的适配器编写一个 Item 点击事件:

class TestAdapter(val context : Context , val data: MutableList<String>)    
	: RecyclerView.Adapter<TestAdapter.TestViewHolder>(){    

	private var mListener : ((Int , String) -> Unit)? = null    

	override fun onBindViewHolder(holder: TestViewHolder?, position: Int) {        
		...        
		holder?.itemView?.setOnClickListener {            
			mListener?.invoke(position, data[position])        
		}    
	}    

	override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): TestViewHolder {        
		return TestViewHolder(View.inflate(context,layoutId,parent))    
	}    

	override fun getItemCount(): Int {        
		return data.size    
	}    

	fun setOnItemClickListener(mListener : (position : Int, item : String) -> Unit){        
		this.mListener = mListener    
	}    

	inner class TestViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView)
}

// 调用
TestAdapter(this,dataList).setOnItemClickListener { position, item ->        
	Toast.makeText(this,"$position \t $item",Toast.LENGTH_SHORT).show()    
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kevin-Dev

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值