1. .let{} 函数
源码 inline 扩展函数 T 是输入类型或者调用对象的类型 R 是返回类型
let函数底层的inline扩展函数+lambda结构
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
函数内使用该对象 都用it指代 返回值为函数块的最后一行或指定return表达式。
1 .let 的第一种用途
object.let {
it.xxx() //在函数体没使用it 来替代 object 对象去访问其共有的属性和方法
}
或者
?.let 第二种用途 进object的不为空操作 为空 则不进行函数内的后续操作
object?.let{ // 表示 object 不为空的后续执行
it.xxx()
}
2.适用场景
对为空的对象进行判空处理
2. with()函数
源码 with函数是接收了两个参数,分别为T类型的对象receiver和一个lambda函数块
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return receiver.block()
}
1. 使用方式 它是将某对象作为函数的参数,在函数块内可以通过 this 指代该对象。
返回值为函数块的最后一行或指定return表达式。
with(object){
//todosometing 直接访问该对象的属性和方法 无需object.xxx 直接xxx
}
2.适用范围
调用同一个类的多个方法时,可以省去类名重复,直接调用类的方法即可,
例如经常用于Android中RecyclerView中onBinderViewHolder中,数据model的属性设置到控件上
3. .run{}函数
源码 run函数实际上可以说是let和with两个函数的结合体,run函数只接收一个lambda函数为参数,
以闭包形式返回,返回值为最后一行的值或者指定的return的表达式。
@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
1. 使用方式
object.run{ 当with 使用
}
或者
object?.run{// with 和?.let 的 结合使用
}
2.适用场景
适用于let,with函数任何场景。因为run函数是let,with两个函数结合体,
准确来说它弥补了let函数在函数体内必须使用it参数替代对象
,在run函数中可以像with函数一样可以省略,
直接访问实例的公有属性和方法,另一方面它弥补了with函数传入对象判空问题,
在run函数中可以像let函数一样做判空处理
4 .apply{}函数
源码 apply函数的返回的是传入对象的本身。
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
1.使用方式
val object=object.apply{
}
2.适用场景
一般用于一个对象实例初始化的时候,需要对对象中的属性进行赋值。
或者动态inflate出一个XML的View的时候需要给View绑定数据也会用到,这种情景非常常见。
特别是在我们开发中会有一些数据model向View model转化实例化的过程中需要用到。
5 .also{}函数
源码 also函数的结构实际上和let很像唯一的区别就是返回值的不一样,
let是以闭包的形式返回,返回函数体内最后一行的值,
如果最后一行为空就返回一个Unit类型的默认值。而also函数返回的则是传入对象的本身
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
1.使用方式
object.also{
}
2.适用场景
适用于let函数的任何场景,also函数和let很像,
只是唯一的不同点就是let函数最后的返回值是最后一行的返回值而also函数的返回值是返回当前的这个对象。
一般可用于多个扩展函数链式调用
6. 总结
函数名 | 函数体内对象使用 | 返回值 | 适用场景 |
---|---|---|---|
let | it.xxx | 最后一行的类型 或者unit 类型返回 |
处理不为null 的数据 |
with | this.xxx或者 xxx 的方法或属性 |
最后一行的类型 或者unit 类型返回 |
调用同一个类的多个方法时,可以省去类名重复, 直接调用类的方法即可,例如经常用于Android 中RecyclerView中onBinderViewHolder中,数 据model的属性设置到控件上 |
run | this.xxx或者 xxx 的方法或属性 |
最后一行的类型 或者unit 类型返回 |
适用于let,with函数任何场景。因为run函数是let, with两个函数结合体,准确来说它弥补了let函数 在函数体内必须使用it参数替代对象,在run函数 中可以像with函数一样可以省略,直接访问实例 的公有属性和方法,另一方面它弥补了with函数 传入对象判空问题,在run函数中可以像let函数 一样做判空处理 |
apply | this.xxx或者 xxx 的方法或属性 |
使用的当前对象 | 1. 适用于run函数的任何场景,一般用于初始化 一个对象实例的时候,操作对象属性,并最终返 回这个对象。2.动态inflate出一个XML的View的 时候需要给View绑定数据也会用到.一般可用于 多个扩展函数链式调用 数据model多层级包裹 判空处理的问题 |
also | it.xxx的方法或属性 | 使用的当前对象 | 适用于let函数的任何场景,一般可用于多个扩展 函数链式调用 |