日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Kotlin標準庫函數使用分析及介紹_Android

作者:niuyongzhi ? 更新時間: 2022-10-31 編程語言

1.apply 函數

apply函數可以看做是一個配置函數。針對apply函數的調用者做一些配置,并把調用者返回。

示例:下面apply的調用者是file,調用完之后,返回的還是file,并在apply函數中,針對file做了一些配置。

    val file = File("d:\\hello.txt").apply {
        setWritable(true)
        setReadable(true)
        setExecutable(false)
    }

apply源碼分析:

1)apply 用inline修飾,是一個內聯函數。

2)定義了一個<T>泛型,T.apply 調用者就是T,:T apply返回的類型也是T

上面的file就相當于T

3)再看apply的參數:block: T.() -> Unit。這是一個匿名函數,T.()->說明接收的是T的函數返回的是Unit類型。

4)在apply內部 調用了這個匿名函數block()也就是T的

5)return this,就是apply 的返回值,返回的是當前調用apply函數的對象。

public inline fun <T> T.apply(block: T.() -> Unit): T {
    block()
    return this
}

2.let 函數

let函數會把調用者作為參數傳到lambda表達式里,可以用it來代替它使用。函數執行完畢,lambda表達式返回的結果,就是let函數返回的結果。

    val hello = "Hello world".let {
        it.replace("world","kotlin")
    }
    //打印結果 Hello kotlin
    println(hello)

看下let函數的定義:

1)let函數也是一個內聯函數。

2)定義了兩個泛型<T,R> T.let(),說明T是let的調用者。

3)block: (T) -> R 說明let接收的是一個匿名函數,匿名函數的參數是T,返回值是R

4): R 說明let函數的返回在也是R,也就是定義的匿名函數的返回值。

5)return block(this) 把當前調用者當做參數傳進來,lambda執行結果返回

上面的示例,調用let后,會把調用者當做參數傳遞到匿名函數也就是lambda中,并把lambda的執行結果,當做是let的結果返回。

inline fun <T, R> T.let(block: (T) -> R): R {
    return block(this)
}

3.run函數

run函數和apply差不多,可以給調用者做配置。唯一的差別是apply返回的是當前調用者對象,而run返回的是lambda執行的結果。

    val text = File("d:\\hello.txt").run {
        setWritable(true)
        setReadable(true)
        setExecutable(false)
        readText()
    }
    println(text)

run函數分析:

1)run函數也是一個內聯函數。

2)有兩個泛型<T,R>,T是當前調用者,R是返回值

3)run接收一個lambda :block: T.() -> R 調用T的方法,并且把執行結果返回

4): R lambda的執行結果,就是run函數的執行結果。我們知道lambda默認會把最后一行的結果返回。

5)return block() 返回lambda的執行結果

inline fun <T, R> T.run(block: T.() -> R): R {
    return block()
}

4.with 函數

with函數是run的變體,他們的功能是一樣的。唯一的不同是調用方式,調用with時,第一個參數需要傳入一個值參。

    val hello = "Hello World"
    val h2 = with(hello) {
        replace("World", "Kotlin")
    }
    println(h2)

源碼分析:

with接收兩個參數,第一個是傳入的值參,第二個是一個lambda表達式。

inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    return receiver.block()
}

5.also

also函數和let函數類似,also也是把調用者作為參數傳遞給lambda,不同點是let返回的是lambda的執行結果,而also返回的是當前調用者對象,這點和apply類似。

這對這個特點,可以實現調用者的鏈式調用。

舉個簡單列子。

雖然對hello做了substring,但并不會改變hello的初始值。因為最后返回的還是調用者對象本身。

    val hello = "Hello world".also {
        println(it.count())
    }.also{
        println(it.substring(0,5))
    }
    println(hello)

源碼分析:

block: (T) -> Unit also接收一個lambda,這個lambda把調用者T當參數傳進來了,block(this)。

return this 又把當前對象返回回去了。

inline fun <T> T.also(block: (T) -> Unit): T {
    block(this)
    return this
}

6.takeIf

takeIf需要判斷lambda表達式中結果,如果true則返回調用者對象,如果是false,則返回null。

如果需要判斷某個條件是否滿足,再決定是否可以給變量賦值或執行某項任務時,takeIf就很好用。takeIf類似于if語句。

示例:如果flag為true,則給hello賦值“Hello world”。

如果flag為false,則返回null,但是后面又有一個?:判斷,就會給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則返回調用者this否則返回null

 inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
    return if (predicate(this)) this else null
}

通過源碼分析,takeIf也會把調用者T當做參數傳到lambda中,這樣我們在lambda中就可以針對調用者做判斷,滿足某些條件則返回調用者對象,如果不滿足,則返回null。

    val hello = "Hello world".takeIf {
        it.count() > 15
    } ?: "hello kotlin world"
    println(hello)

7.takeUnless

takeUnless剛好和takeIf相反,只有給定條件為false時,才會返回takeUnless調用者對象,否則返回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
}

原文鏈接:https://blog.csdn.net/niuyongzhi/article/details/126527605

欄目分類
最近更新