1. .let{} 函數(shù)
源碼 inline 擴展函數(shù) T 是輸入類型或者調(diào)用對象的類型 R 是返回類型
let函數(shù)底層的inline擴展函數(shù)+lambda結(jié)構(gòu)
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
函數(shù)內(nèi)使用該對象 都用it指代 返回值為函數(shù)塊的最后一行或指定return表達式。
1 .let 的第一種用途
object.let {
it.xxx() //在函數(shù)體沒使用it 來替代 object 對象去訪問其共有的屬性和方法
}
或者
?.let 第二種用途 進object的不為空操作 為空 則不進行函數(shù)內(nèi)的后續(xù)操作
object?.let{ // 表示 object 不為空的后續(xù)執(zhí)行
it.xxx()
}
2.適用場景
對為空的對象進行判空處理
2. with()函數(shù)
源碼 with函數(shù)是接收了兩個參數(shù),分別為T類型的對象receiver和一個lambda函數(shù)塊
@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. 使用方式 它是將某對象作為函數(shù)的參數(shù),在函數(shù)塊內(nèi)可以通過 this 指代該對象。
返回值為函數(shù)塊的最后一行或指定return表達式。
with(object){
//todosometing 直接訪問該對象的屬性和方法 無需object.xxx 直接xxx
}
2.適用范圍
調(diào)用同一個類的多個方法時,可以省去類名重復(fù),直接調(diào)用類的方法即可,
例如經(jīng)常用于Android中RecyclerView中onBinderViewHolder中,數(shù)據(jù)model的屬性設(shè)置到控件上
3. .run{}函數(shù)
源碼 run函數(shù)實際上可以說是let和with兩個函數(shù)的結(jié)合體,run函數(shù)只接收一個lambda函數(shù)為參數(shù),
以閉包形式返回,返回值為最后一行的值或者指定的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 的 結(jié)合使用
}
2.適用場景
適用于let,with函數(shù)任何場景。因為run函數(shù)是let,with兩個函數(shù)結(jié)合體,
準確來說它彌補了let函數(shù)在函數(shù)體內(nèi)必須使用it參數(shù)替代對象
,在run函數(shù)中可以像with函數(shù)一樣可以省略,
直接訪問實例的公有屬性和方法,另一方面它彌補了with函數(shù)傳入對象判空問題,
在run函數(shù)中可以像let函數(shù)一樣做判空處理
4 .apply{}函數(shù)
源碼 apply函數(shù)的返回的是傳入對象的本身。
@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.適用場景
一般用于一個對象實例初始化的時候,需要對對象中的屬性進行賦值。
或者動態(tài)inflate出一個XML的View的時候需要給View綁定數(shù)據(jù)也會用到,這種情景非常常見。
特別是在我們開發(fā)中會有一些數(shù)據(jù)model向View model轉(zhuǎn)化實例化的過程中需要用到。
5 .also{}函數(shù)
源碼 also函數(shù)的結(jié)構(gòu)實際上和let很像唯一的區(qū)別就是返回值的不一樣,
let是以閉包的形式返回,返回函數(shù)體內(nèi)最后一行的值,
如果最后一行為空就返回一個Unit類型的默認值。而also函數(shù)返回的則是傳入對象的本身
@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函數(shù)的任何場景,also函數(shù)和let很像,
只是唯一的不同點就是let函數(shù)最后的返回值是最后一行的返回值而also函數(shù)的返回值是返回當前的這個對象。
一般可用于多個擴展函數(shù)鏈式調(diào)用
6. 總結(jié)
| 函數(shù)名 | 函數(shù)體內(nèi)對象使用 | 返回值 | 適用場景 |
|---|---|---|---|
| let | it.xxx | 最后一行的類型 或者unit 類型返回 |
處理不為null 的數(shù)據(jù) |
| with | this.xxx或者 xxx 的方法或?qū)傩?/td> | 最后一行的類型 或者unit 類型返回 |
調(diào)用同一個類的多個方法時,可以省去類名重復(fù), 直接調(diào)用類的方法即可,例如經(jīng)常用于Android 中RecyclerView中onBinderViewHolder中,數(shù) 據(jù)model的屬性設(shè)置到控件上 |
| run | this.xxx或者 xxx 的方法或?qū)傩?/td> | 最后一行的類型 或者unit 類型返回 |
適用于let,with函數(shù)任何場景。因為run函數(shù)是let, with兩個函數(shù)結(jié)合體,準確來說它彌補了let函數(shù) 在函數(shù)體內(nèi)必須使用it參數(shù)替代對象,在run函數(shù) 中可以像with函數(shù)一樣可以省略,直接訪問實例 的公有屬性和方法,另一方面它彌補了with函數(shù) 傳入對象判空問題,在run函數(shù)中可以像let函數(shù) 一樣做判空處理 |
| apply | this.xxx或者 xxx 的方法或?qū)傩?/td> | 使用的當前對象 | 1. 適用于run函數(shù)的任何場景,一般用于初始化 一個對象實例的時候,操作對象屬性,并最終返 回這個對象。2.動態(tài)inflate出一個XML的View的 時候需要給View綁定數(shù)據(jù)也會用到.一般可用于 多個擴展函數(shù)鏈式調(diào)用 數(shù)據(jù)model多層級包裹 判空處理的問題 |
| also | it.xxx的方法或?qū)傩?/td> | 使用的當前對象 | 適用于let函數(shù)的任何場景,一般可用于多個擴展 函數(shù)鏈式調(diào)用 |