kotlin Standard中的內(nèi)聯(lián)函數(shù)示例詳解
let、with、run、apply、also、takeIf、takeUnless、repeat函數(shù)的使用
kotlin Standard.kt文件中,提供了一些內(nèi)聯(lián)函數(shù),這些內(nèi)聯(lián)函數(shù)可以減少代碼量,在使代碼優(yōu)美的同時(shí),打打提高開發(fā)效率。它們分別為:
run、with、let、also、apply
let
let函數(shù)的定義如下:
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
默認(rèn)當(dāng)前這個(gè)對(duì)象作為閉包的it參數(shù),函數(shù)接受一個(gè)lambda函數(shù)塊返回值是函數(shù)里面最后一行,或者指定return
let函數(shù)的一般結(jié)構(gòu)為:
obj.let { it.todo//it指代obj對(duì)象實(shí)例 ... } //在需要判斷obj是否為null時(shí) obj?.let { it.todo//it指代obj對(duì)象實(shí)例 ... }
使用實(shí)例:初始化user
val user = User() val result= user.let { it.account = "12306" it.address = "粵海街道" it.address } println(result) //運(yùn)行結(jié)果 >>粵海街道
適用場(chǎng)景:
- 用let函數(shù)處理需要針對(duì)一個(gè)可null的對(duì)象統(tǒng)一做判空處理
- 明確一個(gè)變量所在特定作用域的范圍
with
with函數(shù)的定義如下:
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
with函數(shù)不是以擴(kuò)展函數(shù)的形式存在,它是將對(duì)象作為參數(shù),在函數(shù)塊內(nèi)通過this指代該對(duì)象。with函數(shù)是接收了兩個(gè)參數(shù),分別為對(duì)象receiver和一個(gè)lambda函數(shù)塊,返回值為函數(shù)塊的最后一行或指定return表達(dá)式。
with的一般結(jié)構(gòu)為:
with(obj){ this.todo todo//this可省略 ... }
使用實(shí)例:將地址影射到UI上
with(user){ tView.text = address }
適用范圍:
適用于調(diào)用一個(gè)類的多個(gè)方法,可以省去對(duì)象名直接調(diào)用方法(例如將數(shù)據(jù)影射到ui上時(shí))
run
run函數(shù)的定義如下:
public inline fun <T, R> T.run(block: T.() -> R): R = block()
run函數(shù)接受一個(gè)lambda函數(shù)塊,以閉包的形式返回函數(shù)塊的最后一行或指定return表達(dá)式。觀察函數(shù)的定義可以發(fā)現(xiàn),run函數(shù)為一個(gè)擴(kuò)展函數(shù),而其接受的參數(shù)和with函數(shù)第二個(gè)參數(shù)相同,run函數(shù)可以理解為let函數(shù)和with函數(shù)的結(jié)合體。
run函數(shù)的一般結(jié)構(gòu)為:
obj.run { this.todo todo//this可省略 ... }
使用實(shí)例:將地址影射到UI上
user.run { tView.text = address }
適用范圍:
適用于let和run函數(shù)的場(chǎng)景,run函數(shù)相較于let函數(shù)省去了必須適用it指代參數(shù)的麻煩,相較于with函數(shù)彌補(bǔ)了對(duì)象判空的問題
also
also函數(shù)的定義如下:
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
also函數(shù)的定義和let函數(shù)的類似,只是also函數(shù)返回的為傳入對(duì)象的本身。
also函數(shù)的一般結(jié)構(gòu)和使用方法和let函數(shù)類似:
obj.also { it.todo//it指代obj對(duì)象實(shí)例 ... } //在需要判斷obj是否為null時(shí) obj?.let { it.todo//it指代obj對(duì)象實(shí)例 ... }
適用范圍:
also函數(shù)返回值微傳入方法的對(duì)象本身,所以可用來(lái)進(jìn)行函數(shù)的鏈?zhǔn)秸{(diào)用
apply
apply函數(shù)的定義如下:
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
apply函數(shù)的定義和run函數(shù)的類似,唯一的區(qū)別就是apply函數(shù)返回的為傳入對(duì)象的本身。
apply函數(shù)一般結(jié)構(gòu)如下:
apply函數(shù)一般結(jié)構(gòu)如下: obj.apply { this.todo todo//this可省略 ... }
使用實(shí)例:給對(duì)象賦值
var user = User().apply { account = "12306" }
適用場(chǎng)景:
apply函數(shù)和run函數(shù)除了返回值外,整體功能和作用類似,一般用于對(duì)象初始化時(shí)對(duì)屬性進(jìn)行賦值。
總結(jié):
這里我們總結(jié)對(duì)比一下這五個(gè)函數(shù),這五個(gè)函數(shù)的特性非常簡(jiǎn)單,區(qū)別也無(wú)非是接受的參數(shù)和返回的類型不同。其中,對(duì)于with,run,apply接收者是this(可以省略),而let和also則使用it接受且不可s省略對(duì)于;
對(duì)于with,run,let返回值是返回值是函數(shù)里面最后一行,或者指定return,而apply和also返回值是調(diào)用者本身。
函數(shù)名 | 接受者 | 返回值 |
---|---|---|
let | it | 最后一行 |
with | this | 最后一行 |
run | this | 最后一行 |
also | it | 調(diào)用者本身 |
apply | this | 調(diào)用者本身 |
如何選擇可以參考下圖
takeIf、takeUnless、repeat
takeIf & takeUnless
takeIf函數(shù)的定義如下:
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null
可以看出:takeIf函數(shù)接受一個(gè)入?yún)㈩愋蜑檎{(diào)用者的類型T,返回值為Boolean類型的lambda函數(shù)塊。takeIf函數(shù)根據(jù)lambda函數(shù)返回值返回的數(shù)據(jù),為true返回調(diào)用者本身,否則返回null
takeUnless函數(shù)的定義如下:
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null
不難看出,takeUnless相對(duì)比takeIf只是在返回值調(diào)用predicate(this)進(jìn)行了取反操作,takeUnless的作用效果和takeIf正好相反!
takeIf函數(shù)一般結(jié)構(gòu)如下:
obj.takeIf{ ... true/fals }
使用實(shí)例:
//根據(jù)age為user賦值,若age在1-100之間,為user.age賦值age,否則user.age為null var age ... user.age = age.takeIf { age in 1..99 }.toString() user.age = age.ta { age in 100..0 }.toString()
repeat
repeat函數(shù)的定義如下:
public inline fun repeat(times: Int, action: (Int) -> Unit) { for (index in 0 until times) { action(index) } }
函數(shù)接受一個(gè)int類型數(shù)據(jù)times,和一個(gè)入?yún)閕nt類型,無(wú)返回值的lambda函數(shù)action,并通過for循環(huán)重復(fù)的調(diào)用times次action函數(shù)
函數(shù)的一般結(jié)構(gòu)如下:
repeat(int){ todo }
使用實(shí)例:
//快速的為list添加十條數(shù)據(jù) var list = ArrayList<User>() repeat(10){ list.add(User()) }
適用場(chǎng)景:該函數(shù)可以用來(lái)避免寫循環(huán)語(yǔ)句,可以用來(lái)遍歷數(shù)據(jù)。
結(jié)語(yǔ):
Kotlin Standard.kt中的標(biāo)準(zhǔn)庫(kù)函數(shù)已基本講解完畢,其中涉及到了高階函數(shù)和lambda函數(shù),相關(guān)知識(shí)可通過官方文檔學(xué)習(xí),同時(shí)建議讀者將每個(gè)函數(shù)都實(shí)際敲一遍,并通過查看他們編譯后的class文件加深對(duì)函數(shù)的理解。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Android中 webView調(diào)用JS出錯(cuò)的解決辦法
這篇文章主要介紹了Android中 webView調(diào)用JS出錯(cuò)的解決辦法,需要的朋友可以參考下2015-01-01Android Studio和Gradle使用不同位置JDK的問題解決
這篇文章主要介紹了Android Studio和Gradle使用不同位置JDK的問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03Android實(shí)現(xiàn)記住用戶名和密碼功能
登陸界面創(chuàng)建一個(gè)復(fù)選按鈕,通過按鈕選取來(lái)進(jìn)行事件處理。若按鈕選中記住賬號(hào)和密碼的信息,本文教大家如何使用Android實(shí)現(xiàn)記住用戶名和密碼功能,感興趣的小伙伴們可以參考一下2016-05-05詳解Android Activity中的幾種監(jiān)聽器和實(shí)現(xiàn)方式
這篇文章主要介紹了Activity中的幾種監(jiān)聽器和實(shí)現(xiàn)方式的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-04-04Android Socket服務(wù)端與客戶端用字符串的方式互相傳遞圖片的方法
這篇文章主要介紹了Android Socket服務(wù)端與客戶端用字符串的方式互相傳遞圖片的方法的相關(guān)資料,需要的朋友可以參考下2016-05-05Android編程獲取網(wǎng)絡(luò)連接方式及判斷手機(jī)卡所屬運(yùn)營(yíng)商的方法
這篇文章主要介紹了Android編程獲取網(wǎng)絡(luò)連接方式及判斷手機(jī)卡所屬運(yùn)營(yíng)商的方法,涉及Android針對(duì)網(wǎng)絡(luò)的判斷及本機(jī)信息的獲取技巧,需要的朋友可以參考下2016-01-01Android中ViewFlipper和AdapterViewFlipper使用的方法實(shí)例
ViewFlipper和AdapterViewFlipper是Android自帶的一個(gè)多頁(yè)面管理控件,下面這篇文章主要給大家介紹了關(guān)于Android中ViewFlipper和AdapterViewFlipper使用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05