Kotlin 中級(jí)篇(八):高階函數(shù)詳解與標(biāo)準(zhǔn)的高階函數(shù)使用

一晰绎、高階函數(shù)介紹

Kotlin中,高階函數(shù)即指:將函數(shù)用作一個(gè)函數(shù)的參數(shù)或者返回值的函數(shù)。

1.1风罩、將函數(shù)用作函數(shù)參數(shù)的情況的高階函數(shù)

這里介紹字符串中的sumBy{}高階函數(shù)。先看一看源碼

// sumBy函數(shù)的源碼
public inline fun CharSequence.sumBy(selector: (Char) -> Int): Int {
    var sum: Int = 0
    for (element in this) {
        sum += selector(element)
    }
    return sum
}

源碼說明:

  1. 大家這里可以不必糾結(jié)inline舵稠,和sumBy函數(shù)前面的CharSequence.超升。因?yàn)檫@是Koltin中的內(nèi)聯(lián)函數(shù)擴(kuò)展功能。在后面的章節(jié)中會(huì)給大家講解到的哺徊。這里主要分析高階函數(shù)室琢,故而這里不多做分析。
  2. 該函數(shù)返回一個(gè)Int類型的值落追。并且接受了一個(gè)selector()函數(shù)作為該函數(shù)的參數(shù)盈滴。其中,selector()函數(shù)接受一個(gè)Char類型的參數(shù)轿钠,并且返回一個(gè)Int類型的值巢钓。
  3. 定義一個(gè)sum變量,并且循環(huán)這個(gè)字符串疗垛,循環(huán)一次調(diào)用一次selector()函數(shù)并加上sum症汹。用作累加。其中this關(guān)鍵字代表字符串本身继谚。

所以這個(gè)函數(shù)的作用是:把字符串中的每一個(gè)字符轉(zhuǎn)換為Int的值烈菌,用于累加阵幸,最后返回累加的值

例:

val testStr = "abc"
val sum = testStr.sumBy { it.toInt() }
println(sum)

輸出結(jié)果為:

294  // 因?yàn)樽址鸻對(duì)應(yīng)的值為97,b對(duì)應(yīng)98,c對(duì)應(yīng)99芽世,故而該值即為 97 + 98 + 99 = 294

1.2挚赊、將函數(shù)用作一個(gè)函數(shù)的返回值的高階函數(shù)。

這里使用官網(wǎng)上的一個(gè)例子來講解济瓢。lock()函數(shù)荠割,先看一看他的源碼實(shí)現(xiàn)

fun <T> lock(lock: Lock, body: () -> T): T {
    lock.lock()
    try {
        return body()
    }
    finally {
        lock.unlock()
    }
}

源碼說明:

  1. 這其中用到了kotlin泛型的知識(shí)點(diǎn),這里贊不考慮旺矾。我會(huì)在后續(xù)的文章為大家講解蔑鹦。
  2. 從源碼可以看出,該函數(shù)接受一個(gè)Lock類型的變量作為參數(shù)1箕宙,并且接受一個(gè)無參且返回類型為T的函數(shù)作為參數(shù)2.
  3. 該函數(shù)的返回值為一個(gè)函數(shù)嚎朽,我們可以看這一句代碼return body()可以看出。

例:使用lock函數(shù)柬帕,下面的代碼都是偽代碼哟忍,我就是按照官網(wǎng)的例子直接拿過來用的

fun toBeSynchronized() = sharedResource.operation()
val result = lock(lock, ::toBeSynchronized)    

其中,::toBeSynchronized即為對(duì)函數(shù)toBeSynchronized()的引用陷寝,其中關(guān)于雙冒號(hào)::的使用在這里不做討論與講解锅很。

上面的寫法也可以寫作:

val result = lock(lock, {sharedResource.operation()} )

1.3、高階函數(shù)的使用

在上面的兩個(gè)例子中凤跑,我們出現(xiàn)了str.sumBy{ it.toInt }這樣的寫法爆安。其實(shí)這樣的寫法在前一章節(jié)Lambda使用中已經(jīng)講解過了。這里主要講高階函數(shù)中對(duì)Lambda語法的簡(jiǎn)寫仔引。

從上面的例子我們的寫法應(yīng)該是這樣的:

str.sumBy( { it.toInt } )

但是根據(jù)Kotlin中的約定扔仓,即當(dāng)函數(shù)中只有一個(gè)函數(shù)作為參數(shù),并且您使用了lambda表達(dá)式作為相應(yīng)的參數(shù)咖耘,則可以省略函數(shù)的小括號(hào)()当辐。故而我們可以寫成:

str.sumBy{ it.toInt }

還有一個(gè)約定,即當(dāng)函數(shù)的最后一個(gè)參數(shù)是一個(gè)函數(shù)鲤看,并且你傳遞一個(gè)lambda表達(dá)式作為相應(yīng)的參數(shù),則可以在圓括號(hào)之外指定它耍群。故而上面例2中的代碼我們可寫成:

val result = lock(lock){
     sharedResource.operation()
}

二义桂、自定義高階函數(shù)

我記得在上一章節(jié)中中我們寫了一個(gè)例子:

// 源代碼
fun test(a : Int , b : Int) : Int{
    return a + b
}

fun sum(num1 : Int , num2 : Int) : Int{
    return num1 + num2
}

// 調(diào)用
test(10,sum(3,5)) // 結(jié)果為:18

// lambda
fun test(a : Int , b : (num1 : Int , num2 : Int) -> Int) : Int{
    return a + b.invoke(3,5)
}

// 調(diào)用
test(10,{ num1: Int, num2: Int ->  num1 + num2 })  // 結(jié)果為:18

可以看出上面的代碼中,直接在我的方法體中寫死了數(shù)值蹈垢,這在開發(fā)中是很不合理的慷吊,并且也不會(huì)這么寫。上面的例子只是在闡述Lambda的語法曹抬。接下來我另舉一個(gè)例子:

例:傳入兩個(gè)參數(shù)溉瓶,并傳入一個(gè)函數(shù)來實(shí)現(xiàn)他們不同的邏輯

例:

private fun resultByOpt(num1 : Int , num2 : Int , result : (Int ,Int) -> Int) : Int{
    return result(num1,num2)
}

private fun testDemo() {
    val result1 = resultByOpt(1,2){
        num1, num2 ->  num1 + num2
    }

    val result2 = resultByOpt(3,4){
        num1, num2 ->  num1 - num2
    }

    val result3 = resultByOpt(5,6){
        num1, num2 ->  num1 * num2
    }

    val result4 = resultByOpt(6,3){
        num1, num2 ->  num1 / num2
    }

    println("result1 = $result1")
    println("result2 = $result2")
    println("result3 = $result3")
    println("result4 = $result4")
}

輸出結(jié)果為:

result1 = 3
result2 = -1
result3 = 30
result4 = 2  

這個(gè)例子是根據(jù)傳入不同的Lambda表達(dá)式,實(shí)現(xiàn)了兩個(gè)數(shù)的+、-堰酿、*疾宏、/
當(dāng)然了触创,在實(shí)際的項(xiàng)目開發(fā)中坎藐,自己去定義高階函數(shù)的實(shí)現(xiàn)是很少了,因?yàn)橛孟到y(tǒng)給我們提供的高階函數(shù)已經(jīng)夠用了哼绑。不過岩馍,當(dāng)我們掌握了Lambda語法以及怎么去定義高階函數(shù)的用法后。在實(shí)際開發(fā)中有了這種需求的時(shí)候也難不倒我們了抖韩。

三蛀恩、常用的標(biāo)準(zhǔn)高階函數(shù)介紹

下面介紹幾個(gè)Kotlin中常用的標(biāo)準(zhǔn)高階函數(shù)。熟練的用好下面的幾個(gè)函數(shù)茂浮,能減少很多的代碼量双谆,并增加代碼的可讀性。下面的幾個(gè)高階函數(shù)的源碼幾乎上都出自Standard.kt文件

3.1励稳、TODO函數(shù)

這個(gè)函數(shù)不是一個(gè)高階函數(shù)佃乘,它只是一個(gè)拋出異常以及測(cè)試錯(cuò)誤的一個(gè)普通函數(shù)。

此函數(shù)的作用:顯示拋出NotImplementedError錯(cuò)誤驹尼。NotImplementedError錯(cuò)誤類繼承至Java中的Error趣避。我們看一看他的源碼就知道了:

public class NotImplementedError(message: String = "An operation is not implemented.") : Error(message)

TODO函數(shù)的源碼

@kotlin.internal.InlineOnly
public inline fun TODO(): Nothing = throw NotImplementedError()

@kotlin.internal.InlineOnly
public inline fun TODO(reason: String): Nothing = 
throw NotImplementedError("An operation is not implemented: $reason")

舉例說明:

fun main(args: Array<String>) {
    TODO("測(cè)試TODO函數(shù),是否顯示拋出錯(cuò)誤")
}

輸出結(jié)果為:


image

如果調(diào)用TODO()時(shí)新翎,不傳參數(shù)的程帕,則會(huì)輸出An operation is not implemented.

3.2 、run()函數(shù)

run函數(shù)這里分為兩種情況講解地啰,因?yàn)樵谠创a中也分為兩個(gè)函數(shù)來實(shí)現(xiàn)的愁拭。采用不同的run函數(shù)會(huì)有不同的效果。

3.2.1亏吝、run()

我們看下其源碼:

public inline fun <R> run(block: () -> R): R {
contract {
    callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}

關(guān)于contract這部分代碼小生也不是很懂其意思岭埠。在一些大牛的blog上說是其編輯器對(duì)上下文的推斷。但是我也不知道對(duì)不對(duì)蔚鸥,因?yàn)樵诠倬W(wǎng)中惜论,對(duì)這個(gè)東西也沒有講解到。不過這個(gè)單詞的意思是契約止喷,合同等等意思馆类。我想應(yīng)該和這個(gè)有關(guān)。在這里我就不做深究了弹谁。主要講講run{}函數(shù)的用法其含義乾巧。

這里我們只關(guān)心return block()這行代碼句喜。從源碼中我們可以看出,run函數(shù)僅僅是執(zhí)行了我們的block()沟于,即一個(gè)Lambda表達(dá)式咳胃,而后返回了執(zhí)行的結(jié)果。

用法1:

當(dāng)我們需要執(zhí)行一個(gè)代碼塊的時(shí)候就可以用到這個(gè)函數(shù),并且這個(gè)代碼塊是獨(dú)立的社裆。即我可以在run()函數(shù)中寫一些和項(xiàng)目無關(guān)的代碼拙绊,因?yàn)樗粫?huì)影響項(xiàng)目的正常運(yùn)行。

例: 在一個(gè)函數(shù)中使用

private fun testRun1() {
    val str = "kotlin"

    run{
        val str = "java"   // 和上面的變量不會(huì)沖突
        println("str = $str")
    }

    println("str = $str")
}    

輸出結(jié)果:

str = java
str = kotlin

用法2:

因?yàn)?code>run函數(shù)執(zhí)行了我傳進(jìn)去的lambda表達(dá)式并返回了執(zhí)行的結(jié)果泳秀,所以當(dāng)一個(gè)業(yè)務(wù)邏輯都需要執(zhí)行同一段代碼而根據(jù)不同的條件去判斷得到不同結(jié)果的時(shí)候标沪。可以用到run函數(shù)

例:都要獲取字符串的長(zhǎng)度嗜傅。

val index = 3
val num = run {
    when(index){
        0 -> "kotlin"
        1 -> "java"
        2 -> "php"
        3 -> "javaScript"
        else -> "none"
    }
}.length
println("num = $num")

輸出結(jié)果為:

num = 10

當(dāng)然這個(gè)例子沒什么實(shí)際的意義金句。

3.2.2、T.run()

其實(shí)T.run()函數(shù)和run()函數(shù)差不多吕嘀,關(guān)于這兩者之間的差別我們看看其源碼實(shí)現(xiàn)就明白了:

public inline fun <T, R> T.run(block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

從源碼中我們可以看出违寞,block()這個(gè)函數(shù)參數(shù)是一個(gè)擴(kuò)展在T類型下的函數(shù)。這說明我的block()函數(shù)可以可以使用當(dāng)前對(duì)象的上下文偶房。所以當(dāng)我們傳入的lambda表達(dá)式想要使用當(dāng)前對(duì)象的上下文的時(shí)候趁曼,我們可以使用這個(gè)函數(shù)。

用法:

這里就不能像上面run()函數(shù)那樣當(dāng)做單獨(dú)的一個(gè)代碼塊來使用棕洋。

例:

val str = "kotlin"
str.run {
    println( "length = ${this.length}" )
    println( "first = ${first()}")
    println( "last = ${last()}" )
}

輸出結(jié)果為:

length = 6
first = k
last = n

在其中挡闰,可以使用this關(guān)鍵字,因?yàn)樵谶@里它就代碼str這個(gè)對(duì)象掰盘,也可以省略摄悯。因?yàn)樵谠创a中我們就可以看出,block()
就是一個(gè)T類型的擴(kuò)展函數(shù)愧捕。

這在實(shí)際的開發(fā)當(dāng)中我們可以這樣用:

例: 為TextView設(shè)置屬性奢驯。

val mTvBtn = findViewById<TextView>(R.id.text)
mTvBtn.run{
    text = "kotlin"
    textSize = 13f
    ...
}

3.3 、with()函數(shù)

其實(shí)with()函數(shù)和T.run()函數(shù)的作用是相同的次绘,我們這里看下其實(shí)現(xiàn)源碼:

public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}

這里我們可以看出和T.run()函數(shù)的源代碼實(shí)現(xiàn)沒有太大的差別瘪阁。故而這兩個(gè)函數(shù)的區(qū)別在于:

  1. with是正常的高階函數(shù),T.run()是擴(kuò)展的高階函數(shù)邮偎。
  2. with函數(shù)的返回值指定了receiver為接收者罗洗。

故而上面的T.run()函數(shù)的列子我也可用with來實(shí)現(xiàn)相同的效果:

例:

val str = "kotlin"
with(str) {
    println( "length = ${this.length}" )
    println( "first = ${first()}")
    println( "last = ${last()}" )
}

輸出結(jié)果為:

length = 6
first = k
last = n

TextView設(shè)置屬性,也可以用它來實(shí)現(xiàn)钢猛。這里我就不舉例了。

在上面舉例的時(shí)候轩缤,都是正常的列子命迈,這里舉一個(gè)特例:當(dāng)我的對(duì)象可為null的時(shí)候贩绕,看兩個(gè)函數(shù)之間的便利性。

例:

val newStr : String? = "kotlin"

with(newStr){
    println( "length = ${this?.length}" )
    println( "first = ${this?.first()}")
    println( "last = ${this?.last()}" )
}

newStr?.run {
    println( "length = $length" )
    println( "first = ${first()}")
    println( "last = ${last()}" )
}

從上面的代碼我們就可以看出壶愤,當(dāng)我們使用對(duì)象可為null時(shí)淑倾,使用T.run()比使用with()函數(shù)從代碼的可讀性與簡(jiǎn)潔性來說要好一些。當(dāng)然關(guān)于怎樣去選擇使用這兩個(gè)函數(shù)征椒,就得根據(jù)實(shí)際的需求以及自己的喜好了娇哆。

3.4、T.apply()函數(shù)

我們先看下T.apply()函數(shù)的源碼:

public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

T.apply()源碼中在結(jié)合前面提到的T.run()函數(shù)的源碼我們可以得出,這兩個(gè)函數(shù)的邏輯差不多勃救,唯一的區(qū)別是T,apply執(zhí)行完了block()函數(shù)后碍讨,返回了自身對(duì)象。而T.run是返回了執(zhí)行的結(jié)果蒙秒。

故而: T.apply的作用除了實(shí)現(xiàn)能實(shí)現(xiàn)T.run函數(shù)的作用外勃黍,還可以后續(xù)的再對(duì)此操作。下面我們看一個(gè)例子:

例:為TextView設(shè)置屬性后晕讲,再設(shè)置點(diǎn)擊事件等

val mTvBtn = findViewById<TextView>(R.id.text)
mTvBtn.apply{
    text = "kotlin"
    textSize = 13f
    ...
}.apply{
    // 這里可以繼續(xù)去設(shè)置屬性或一些TextView的其他一些操作
}.apply{
    setOnClickListener{ .... }
}

或者:設(shè)置為Fragment設(shè)置數(shù)據(jù)傳遞

// 原始方法
fun newInstance(id : Int , name : String , age : Int) : MimeFragment{
        val fragment = MimeFragment()
        fragment.arguments.putInt("id",id)
        fragment.arguments.putString("name",name)
        fragment.arguments.putInt("age",age)

        return fragment
}

// 改進(jìn)方法
fun newInstance(id : Int , name : String , age : Int) = MimeFragment().apply {
        arguments.putInt("id",id)
        arguments.putString("name",name)
        arguments.putInt("age",age)
}

3.5覆获、T.also()函數(shù)

關(guān)于T.also函數(shù)來說,它和T.apply很相似瓢省,弄息。我們先看看其源碼的實(shí)現(xiàn):

public inline fun <T> T.also(block: (T) -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block(this)
    return this
}

從上面的源碼在結(jié)合T.apply函數(shù)的源碼我們可以看出: T.also函數(shù)中的參數(shù)block函數(shù)傳入了自身對(duì)象。故而這個(gè)函數(shù)的作用是用用block函數(shù)調(diào)用自身對(duì)象勤婚,最后在返回自身對(duì)象

這里舉例一個(gè)簡(jiǎn)單的例子摹量,并用實(shí)例說明其和T.apply的區(qū)別

例:

"kotlin".also {
    println("結(jié)果:${it.plus("-java")}")
}.also {
    println("結(jié)果:${it.plus("-php")}")
}

"kotlin".apply {
    println("結(jié)果:${this.plus("-java")}")
}.apply {
    println("結(jié)果:${this.plus("-php")}")
}

他們的輸出結(jié)果是相同的:

結(jié)果:kotlin-java
結(jié)果:kotlin-php

結(jié)果:kotlin-java
結(jié)果:kotlin-php

從上面的實(shí)例我們可以看出,他們的區(qū)別在于蛔六,T.also中只能使用it調(diào)用自身,而T.apply中只能使用this調(diào)用自身荆永。因?yàn)樵谠创a中T.also是執(zhí)行block(this)后在返回自身。而T.apply是執(zhí)行block()后在返回自身国章。這就是為什么在一些函數(shù)中可以使用it,而一些函數(shù)中只能使用this的關(guān)鍵所在

3.6具钥、T.let()函數(shù)

在前面講解空安全、可空屬性章節(jié)中液兽,我們講解到可以使用T.let()函數(shù)來規(guī)避空指針的問題骂删。有興趣的朋友可以去看看我的Kotlin——初級(jí)篇(六):空類型、空安全四啰、非空斷言宁玫、類型轉(zhuǎn)換等特性總結(jié)這篇文章。但是在這篇文章中柑晒,我們只講到了它的使用欧瘪。故而今天來說一下他的源碼實(shí)現(xiàn):

public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}

從上面的源碼中我們可以得出,它其實(shí)和T.also以及T.apply都很相似匙赞。而T.let的作用也不僅僅在使用空安全這一個(gè)點(diǎn)上佛掖。用T.let也可實(shí)現(xiàn)其他操作

例:

"kotlin".let {
    println("原字符串:$it")         // kotlin
    it.reversed()
}.let {
    println("反轉(zhuǎn)字符串后的值:$it")     // niltok
    it.plus("-java")
}.let {
    println("新的字符串:$it")          // niltok-java
}

"kotlin".also {
    println("原字符串:$it")     // kotlin
    it.reversed()
}.also {
    println("反轉(zhuǎn)字符串后的值:$it")     // kotlin
    it.plus("-java")
}.also {
    println("新的字符串:$it")        // kotlin
}

"kotlin".apply {
    println("原字符串:$this")     // kotlin
    this.reversed()
}.apply {
    println("反轉(zhuǎn)字符串后的值:$this")     // kotlin
    this.plus("-java")
}.apply {
    println("新的字符串:$this")        // kotlin
}

輸出結(jié)果看是否和注釋的結(jié)果一樣呢:

原字符串:kotlin
反轉(zhuǎn)字符串后的值:niltok
新的字符串:niltok-java

原字符串:kotlin
反轉(zhuǎn)字符串后的值:kotlin
新的字符串:kotlin

原字符串:kotlin
反轉(zhuǎn)字符串后的值:kotlin
新的字符串:kotlin

3.7辕翰、T.takeIf()函數(shù)

從函數(shù)的名字我們可以看出许溅,這是一個(gè)關(guān)于條件判斷的函數(shù),我們?cè)诳雌湓创a實(shí)現(xiàn):

public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
    contract {
        callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
    }
    return if (predicate(this)) this else null
}

從源碼中我們可以得出這個(gè)函數(shù)的作用是:

傳入一個(gè)你希望的一個(gè)條件损敷,如果對(duì)象符合你的條件則返回自身辽俗,反之,則返回null拴魄。

例: 判斷一個(gè)字符串是否由某一個(gè)字符起始冗茸,若條件成立則返回自身,反之匹中,則返回null

val str = "kotlin"

val result = str.takeIf {
    it.startsWith("ko") 
}

println("result = $result")

輸出結(jié)果為:

result = kotlin

3.8夏漱、T.takeUnless()函數(shù)

這個(gè)函數(shù)的作用和T.takeIf()函數(shù)的作用是一樣的。只是和其的邏輯是相反的职员。即:傳入一個(gè)你希望的一個(gè)條件麻蹋,如果對(duì)象符合你的條件則返回null,反之焊切,則返回自身扮授。

這里看一看它的源碼就明白了。

public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? {
    contract {
        callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
    }
    return if (!predicate(this)) this else null
}

這里就舉和T.takeIf()函數(shù)中一樣的例子专肪,看他的結(jié)果和T.takeIf()中的結(jié)果是不是相反的刹勃。

例:

val str = "kotlin"

val result = str.takeUnless {
    it.startsWith("ko") 
}

println("result = $result")

輸出結(jié)果為:

result = null

3.8、repeat()函數(shù)

首先嚎尤,我們從這個(gè)函數(shù)名就可以看出是關(guān)于重復(fù)相關(guān)的一個(gè)函數(shù)荔仁,再看起源碼,從源碼的實(shí)現(xiàn)來說明這個(gè)函數(shù)的作用:

public inline fun repeat(times: Int, action: (Int) -> Unit) {
    contract { callsInPlace(action) }

    for (index in 0..times - 1) {
        action(index)
    }
}

從上面的代碼我們可以看出這個(gè)函數(shù)的作用是:

根據(jù)傳入的重復(fù)次數(shù)去重復(fù)執(zhí)行一個(gè)我們想要的動(dòng)作(函數(shù))

例:

repeat(5){
    println("我是重復(fù)的第${it + 1}次芽死,我的索引為:$it")
}

輸出結(jié)果為:

我是重復(fù)的第1次乏梁,我的索引為:0
我是重復(fù)的第2次,我的索引為:1
我是重復(fù)的第3次关贵,我的索引為:2
我是重復(fù)的第4次遇骑,我的索引為:3
我是重復(fù)的第5次,我的索引為:4

3.9揖曾、lazy()函數(shù)

關(guān)于Lazy()函數(shù)來說落萎,它共實(shí)現(xiàn)了4個(gè)重載函數(shù),都是用于延遲操作炭剪,不過這里不多做介紹练链。因?yàn)樵趯?shí)際的項(xiàng)目開發(fā)中常用都是用于延遲初始化屬性。

四奴拦、對(duì)標(biāo)準(zhǔn)的高階函數(shù)總結(jié)

關(guān)于重復(fù)使用同一個(gè)函數(shù)的情況一般都只有T.also媒鼓、T.letT.apply這三個(gè)函數(shù)。而這個(gè)三個(gè)函數(shù)在上面講解這些函數(shù)的時(shí)候都用實(shí)例講解了他們的區(qū)別绿鸣。故而這里不做詳細(xì)實(shí)例介紹瓷产。并且連貫著使用這些高階函數(shù)去處理一定的邏輯,在實(shí)際項(xiàng)目中很少會(huì)這樣做枚驻。一般都是單獨(dú)使用一個(gè),或者兩個(gè)株旷、三個(gè)這個(gè)連貫這用再登。

關(guān)于他們之間的區(qū)別,以及他們用于實(shí)際項(xiàng)目中在一定的需求下到底該怎樣去選擇哪一個(gè)函數(shù)進(jìn)行使用希望大家詳細(xì)的看下他們的源碼并且根據(jù)我前面說寫的實(shí)例進(jìn)行分析晾剖。

大家也可以參考這篇文章:
掌握Kotlin標(biāo)準(zhǔn)函數(shù):run, with, let, also and apply

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末锉矢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子齿尽,更是在濱河造成了極大的恐慌沽损,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件循头,死亡現(xiàn)場(chǎng)離奇詭異绵估,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)卡骂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門国裳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人全跨,你說我怎么就攤上這事缝左。” “怎么了浓若?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵渺杉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我挪钓,道長(zhǎng)是越,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任诵原,我火速辦了婚禮英妓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绍赛。我一直安慰自己蔓纠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布吗蚌。 她就那樣靜靜地躺著腿倚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚯妇。 梳的紋絲不亂的頭發(fā)上敷燎,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天暂筝,我揣著相機(jī)與錄音,去河邊找鬼硬贯。 笑死焕襟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的饭豹。 我是一名探鬼主播鸵赖,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼拄衰!你這毒婦竟也來了它褪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤翘悉,失蹤者是張志新(化名)和其女友劉穎茫打,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妖混,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡老赤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了源葫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诗越。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖息堂,靈堂內(nèi)的尸體忽然破棺而出嚷狞,到底是詐尸還是另有隱情,我是刑警寧澤荣堰,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布床未,位于F島的核電站,受9級(jí)特大地震影響振坚,放射性物質(zhì)發(fā)生泄漏薇搁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一渡八、第九天 我趴在偏房一處隱蔽的房頂上張望啃洋。 院中可真熱鬧,春花似錦屎鳍、人聲如沸宏娄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽孵坚。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卖宠,已是汗流浹背巍杈。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扛伍,地道東北人筷畦。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像刺洒,于是被迫代替她去往敵國(guó)和親汁咏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容