Kotlin標(biāo)準(zhǔn)庫函數(shù)使用分析及介紹
1.apply 函數(shù)
apply函數(shù)可以看做是一個(gè)配置函數(shù)。針對apply函數(shù)的調(diào)用者做一些配置,并把調(diào)用者返回。
示例:下面apply的調(diào)用者是file,調(diào)用完之后,返回的還是file,并在apply函數(shù)中,針對file做了一些配置。
val file = File("d:\\hello.txt").apply { setWritable(true) setReadable(true) setExecutable(false) }
apply源碼分析:
1)apply 用inline修飾,是一個(gè)內(nèi)聯(lián)函數(shù)。
2)定義了一個(gè)<T>泛型,T.apply 調(diào)用者就是T,:T apply返回的類型也是T
上面的file就相當(dāng)于T
3)再看apply的參數(shù):block: T.() -> Unit。這是一個(gè)匿名函數(shù),T.()->說明接收的是T的函數(shù)返回的是Unit類型。
4)在apply內(nèi)部 調(diào)用了這個(gè)匿名函數(shù)block()也就是T的
5)return this,就是apply 的返回值,返回的是當(dāng)前調(diào)用apply函數(shù)的對象。
public inline fun <T> T.apply(block: T.() -> Unit): T { block() return this }
2.let 函數(shù)
let函數(shù)會(huì)把調(diào)用者作為參數(shù)傳到lambda表達(dá)式里,可以用it來代替它使用。函數(shù)執(zhí)行完畢,lambda表達(dá)式返回的結(jié)果,就是let函數(shù)返回的結(jié)果。
val hello = "Hello world".let { it.replace("world","kotlin") } //打印結(jié)果 Hello kotlin println(hello)
看下let函數(shù)的定義:
1)let函數(shù)也是一個(gè)內(nèi)聯(lián)函數(shù)。
2)定義了兩個(gè)泛型<T,R> T.let(),說明T是let的調(diào)用者。
3)block: (T) -> R 說明let接收的是一個(gè)匿名函數(shù),匿名函數(shù)的參數(shù)是T,返回值是R
4): R 說明let函數(shù)的返回在也是R,也就是定義的匿名函數(shù)的返回值。
5)return block(this) 把當(dāng)前調(diào)用者當(dāng)做參數(shù)傳進(jìn)來,lambda執(zhí)行結(jié)果返回
上面的示例,調(diào)用let后,會(huì)把調(diào)用者當(dāng)做參數(shù)傳遞到匿名函數(shù)也就是lambda中,并把lambda的執(zhí)行結(jié)果,當(dāng)做是let的結(jié)果返回。
inline fun <T, R> T.let(block: (T) -> R): R { return block(this) }
3.run函數(shù)
run函數(shù)和apply差不多,可以給調(diào)用者做配置。唯一的差別是apply返回的是當(dāng)前調(diào)用者對象,而run返回的是lambda執(zhí)行的結(jié)果。
val text = File("d:\\hello.txt").run { setWritable(true) setReadable(true) setExecutable(false) readText() } println(text)
run函數(shù)分析:
1)run函數(shù)也是一個(gè)內(nèi)聯(lián)函數(shù)。
2)有兩個(gè)泛型<T,R>,T是當(dāng)前調(diào)用者,R是返回值
3)run接收一個(gè)lambda :block: T.() -> R 調(diào)用T的方法,并且把執(zhí)行結(jié)果返回
4): R lambda的執(zhí)行結(jié)果,就是run函數(shù)的執(zhí)行結(jié)果。我們知道lambda默認(rèn)會(huì)把最后一行的結(jié)果返回。
5)return block() 返回lambda的執(zhí)行結(jié)果
inline fun <T, R> T.run(block: T.() -> R): R { return block() }
4.with 函數(shù)
with函數(shù)是run的變體,他們的功能是一樣的。唯一的不同是調(diào)用方式,調(diào)用with時(shí),第一個(gè)參數(shù)需要傳入一個(gè)值參。
val hello = "Hello World" val h2 = with(hello) { replace("World", "Kotlin") } println(h2)
源碼分析:
with接收兩個(gè)參數(shù),第一個(gè)是傳入的值參,第二個(gè)是一個(gè)lambda表達(dá)式。
inline fun <T, R> with(receiver: T, block: T.() -> R): R { return receiver.block() }
5.also
also函數(shù)和let函數(shù)類似,also也是把調(diào)用者作為參數(shù)傳遞給lambda,不同點(diǎn)是let返回的是lambda的執(zhí)行結(jié)果,而also返回的是當(dāng)前調(diào)用者對象,這點(diǎn)和apply類似。
這對這個(gè)特點(diǎn),可以實(shí)現(xiàn)調(diào)用者的鏈?zhǔn)秸{(diào)用。
舉個(gè)簡單列子。
雖然對hello做了substring,但并不會(huì)改變hello的初始值。因?yàn)樽詈蠓祷氐倪€是調(diào)用者對象本身。
val hello = "Hello world".also { println(it.count()) }.also{ println(it.substring(0,5)) } println(hello)
源碼分析:
block: (T) -> Unit also接收一個(gè)lambda,這個(gè)lambda把調(diào)用者T當(dāng)參數(shù)傳進(jìn)來了,block(this)。
return this 又把當(dāng)前對象返回回去了。
inline fun <T> T.also(block: (T) -> Unit): T { block(this) return this }
6.takeIf
takeIf需要判斷l(xiāng)ambda表達(dá)式中結(jié)果,如果true則返回調(diào)用者對象,如果是false,則返回null。
如果需要判斷某個(gè)條件是否滿足,再?zèng)Q定是否可以給變量賦值或執(zhí)行某項(xiàng)任務(wù)時(shí),takeIf就很好用。takeIf類似于if語句。
示例:如果flag為true,則給hello賦值“Hello world”。
如果flag為false,則返回null,但是后面又有一個(gè)?:判斷,就會(huì)給hello賦值“hello null”
var flag = false val hello = "Hello world".takeIf { false } ?: "hello null" println(hello)
源碼分析:
從if (predicate(this)) this else null可以看出,如果predicate(this)為true則返回調(diào)用者this否則返回null
inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? { return if (predicate(this)) this else null }
通過源碼分析,takeIf也會(huì)把調(diào)用者T當(dāng)做參數(shù)傳到lambda中,這樣我們在lambda中就可以針對調(diào)用者做判斷,滿足某些條件則返回調(diào)用者對象,如果不滿足,則返回null。
val hello = "Hello world".takeIf { it.count() > 15 } ?: "hello kotlin world" println(hello)
7.takeUnless
takeUnless剛好和takeIf相反,只有給定條件為false時(shí),才會(huì)返回takeUnless調(diào)用者對象,否則返回null。
val hello = "Hello world".takeUnless { it.count() > 15 } ?: "hello kotlin world" println(hello)
源碼:
if (!predicate(this)) 剛好和takeIf中的相反。
inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? { return if (!predicate(this)) this else null }
到此這篇關(guān)于Kotlin標(biāo)準(zhǔn)庫函數(shù)使用分析及介紹的文章就介紹到這了,更多相關(guān)Kotlin標(biāo)準(zhǔn)庫函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Kotlin?掛起函數(shù)CPS轉(zhuǎn)換原理解析
這篇文章主要為大家介紹了Kotlin?掛起函數(shù)CPS轉(zhuǎn)換原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12Android實(shí)現(xiàn)字母導(dǎo)航控件的示例代碼
這篇文章主要介紹了通過自定義View實(shí)現(xiàn)字母導(dǎo)航控件的示例代碼,文中的實(shí)現(xiàn)過程講解詳細(xì),對我們學(xué)習(xí)或工作有一定幫助,感興趣的可以學(xué)習(xí)一下2022-01-01android用鬧鐘定時(shí)做http請求推送的解決方案
這篇文章主要為大家詳細(xì)介紹了android用鬧鐘定時(shí)做http請求推送的解決方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01安卓(android)怎么實(shí)現(xiàn)下拉刷新
這里我們將采取的方案是使用組合View的方式,先自定義一個(gè)布局繼承自LinearLayout,然后在這個(gè)布局中加入下拉頭和ListView這兩個(gè)子元素,并讓這兩個(gè)子元素縱向排列。對安卓(android)怎么實(shí)現(xiàn)下拉刷新的相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-04-04Android編程實(shí)現(xiàn)TextView部分顏色變動(dòng)的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)TextView部分顏色變動(dòng)的方法,涉及Android針對TextView樣式操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11Android實(shí)現(xiàn)檢測手機(jī)多點(diǎn)觸摸點(diǎn)數(shù)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)檢測手機(jī)多點(diǎn)觸摸點(diǎn)數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05