kotlin之Run疗疟、With该默、Let、Apply策彤、Also

[toc]
了解內(nèi)聯(lián)函數(shù)前先了解下lambda表達(dá)式

lambda

Lambda表達(dá)式的本質(zhì)其實(shí)是匿名函數(shù)栓袖,因?yàn)樵谄涞讓訉?shí)現(xiàn)中還是通過(guò)匿名函數(shù)來(lái)實(shí)現(xiàn)的。但是我們?cè)谟玫臅r(shí)候不必關(guān)心起底層實(shí)現(xiàn)店诗。不過(guò)Lambda的出現(xiàn)確實(shí)是減少了代碼量的編寫裹刮,同時(shí)也是代碼變得更加簡(jiǎn)潔明了。

使用

  1. 無(wú)參數(shù)的情況 :
  val/var 變量名 = { 操作的代碼 }

  2. 有參數(shù)的情況
  val/var 變量名 : (參數(shù)的類型庞瘸,參數(shù)類型捧弃,...) -> 返回值類型 = {參數(shù)1,參數(shù)2擦囊,... -> 操作參數(shù)的代碼 }

  可等價(jià)于
  // 此種寫法:即表達(dá)式的返回值類型會(huì)根據(jù)操作的代碼自推導(dǎo)出來(lái)违霞。
  val/var 變量名 = { 參數(shù)1 : 類型,參數(shù)2 : 類型, ... -> 操作參數(shù)的代碼 }

  3. lambda表達(dá)式作為函數(shù)中的參數(shù)的時(shí)候瞬场,這里舉一個(gè)例子:
  fun test(a : Int, 參數(shù)名 : (參數(shù)1 : 類型买鸽,參數(shù)2 : 類型, ... ) -> 表達(dá)式返回類型){
      ...
  }

實(shí)例講解

  • 無(wú)參數(shù)的情況
 // 源代碼
 fun test(){ println("無(wú)參數(shù)") }

  // lambda代碼
  val test = { println("無(wú)參數(shù)") }

  // 調(diào)用
  test()  => 結(jié)果為:無(wú)參數(shù)
  • 有參數(shù)的情況
// 源代碼
    fun test(a : Int , b : Int) : Int{
        return a + b
    }

    // lambda
    val test : (Int , Int) -> Int = {a , b -> a + b}
    // 或者
    val test = {a : Int , b : Int -> a + b}
    
    // 調(diào)用
    test(3,5) => 結(jié)果為:8
  • lambda表達(dá)式作為函數(shù)中的參數(shù)的時(shí)候
// 源代碼
    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

T.()->Unit 、 ()->Unit的區(qū)別

  1. ()->Unit與(T) -> Unit是相同的贯被,是lambda的函數(shù)參數(shù)形式眼五,只是一個(gè)帶參,一個(gè)不帶參彤灶。(T) -> Unit通過(guò)形參T可將對(duì)象作為實(shí)參傳給函數(shù)看幼,所以函數(shù)體里能通過(guò)it或者指定名稱的方式來(lái)訪問(wèn)該對(duì)象
  2. T.()->Unit 等同于為T定義了一個(gè)無(wú)參數(shù)的擴(kuò)展函數(shù),所以在函數(shù)體內(nèi)可以直接通過(guò)this或省略來(lái)訪問(wèn)T代表的對(duì)象

實(shí)例講解

(T) -> Unit

fun Person.alsoWithReceiver(block:(Person) ->Unit):Person{
    block(this)
    return this
}
//構(gòu)造的參數(shù)是it
person.alsoWithReceiver {
        it.setNewName("haha bro")
    }.getOldName()
    

T.()->Unit

fun Person.ApplyNew(block:Person.() ->Unit):Person{
    block()
    return this
}
//構(gòu)造的參數(shù)是this
person.ApplyNew {
    this.setNewName("aa")
}

1.Let

1.1作用

  1. 使用it替代object對(duì)象去訪問(wèn)其公有的屬性 & 方法
  2. 判斷object為null的操作

1.2底層結(jié)構(gòu)

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

1.3使用方法

// 作用1:使用it替代object對(duì)象去訪問(wèn)其公有的屬性 & 方法
object.let{
   it.todo()
}

// 作用2:判斷object為null的操作
object?.let{//表示object不為null的條件下幌陕,才會(huì)去執(zhí)行l(wèi)et函數(shù)體
   it.todo()
}

// 注:返回值 = 最后一行 / return的表達(dá)式

1.4實(shí)例講解

// 使用Java
if( mVar != null ){
    mVar.function1();
    mVar.function2();
    mVar.function3();
}

// 使用kotlin(無(wú)使用let函數(shù))
mVar?.function1()
mVar?.function2()
mVar?.function3()

// 使用kotlin(使用let函數(shù))
// 方便了統(tǒng)一判空的處理 & 確定了mVar變量的作用域
mVar?.let {
       it.function1()
       it.function2()
       it.function3()
}

2.Also

2.1作用

類似let函數(shù)诵姜,但區(qū)別在于返回值:

let函數(shù):返回值 = 最后一行 / return的表達(dá)式
also函數(shù):返回值 = 傳入的對(duì)象的本身

2.2底層結(jié)構(gòu)

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

2.3使用方法

// 作用1:使用it替代object對(duì)象去訪問(wèn)其公有的屬性 & 方法
object.also{
    //this 可省略
   this.todo()
}

// 作用2:判斷object為null的操作
object?.also{//表示object不為null的條件下,才會(huì)去執(zhí)行l(wèi)et函數(shù)體
   todo()
}

2.4實(shí)例講解

// let函數(shù)
var result = mVar.let {
               it.function1()
               it.function2()
               it.function3()
               999
}
// 最終結(jié)果 = 返回999給變量result

// also函數(shù)
var result = mVar.also {
               it.function1()
               it.function2()
               it.function3()
               999
}.todo()
// 最終結(jié)果 = 返回一個(gè)mVar對(duì)象給變量result

3.with

3.1作用

調(diào)用同一個(gè)對(duì)象的多個(gè)方法 / 屬性時(shí)搏熄,可以省去對(duì)象名重復(fù)棚唆,直接調(diào)用方法名 / 屬性即可

3.2底層結(jié)構(gòu)

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

3.3使用方法

with(object){
   // ... 
 }

// 返回值 = 函數(shù)塊的最后一行 / return表達(dá)式
3.4 使用示例

3.4實(shí)例講解

// 此處要調(diào)用people的name 和 age屬性
// kotlin
val people = People("carson", 25)
with(people) {
    this.setName("zhangsan")
    setAge(15)
    println("my name is $name, I am $age years old")
}

// Java
User peole = new People("carson", 25);
String var1 = "my name is " + peole.name + ", I am " + peole.age + " years old";
System.out.println(var1);

4.Run

4.1作用

結(jié)合了let、with兩個(gè)函數(shù)的作用搬卒,即:

1. 調(diào)用同一個(gè)對(duì)象的多個(gè)方法 / 屬性時(shí)瑟俭,可以省去對(duì)象名重復(fù),直接調(diào)用方法名 / 屬性即可
2. 定義一個(gè)變量在特定作用域內(nèi)
3. 統(tǒng)一做判空處理

4.2底層結(jié)構(gòu)

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

4.3使用方法

object.run{
// ... 
}
// 返回值 = 函數(shù)塊的最后一行 / return表達(dá)式

4.4實(shí)例講解

// 此處要調(diào)用people的name 和 age屬性契邀,且要判空
// kotlin
val people = People("carson", 25)
people?.run{
    println("my name is $name, I am $age years old")
}

// Java
User peole = new People("carson", 25);
String var1 = "my name is " + peole.name + ", I am " + peole.age + " years old";
System.out.println(var1);

5.Apply

5.1作用

與run函數(shù)類似摆寄,但區(qū)別在于返回值:

1. run函數(shù)返回最后一行的值 / 表達(dá)式
2. apply函數(shù)返回傳入的對(duì)象的本身

5.2底層結(jié)構(gòu)

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

5.3使用方法

object.apply{
// ... 
}
// 返回值 = object

5.4實(shí)例講解

// run函數(shù)
val people = People("carson", 25)
val result = people?.run{
    println("my name is $name, I am $age years old")
    999
}
// 最終結(jié)果 = 返回999給變量result

// Java
val people = People("carson", 25)
val result = people?.run{
    println("my name is $name, I am $age years old")
    999
}
// 最終結(jié)果 = 返回一個(gè)people對(duì)象給變量result
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子微饥,更是在濱河造成了極大的恐慌逗扒,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欠橘,死亡現(xiàn)場(chǎng)離奇詭異矩肩,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)肃续,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門黍檩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人始锚,你說(shuō)我怎么就攤上這事刽酱。” “怎么了瞧捌?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵棵里,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我姐呐,道長(zhǎng)殿怜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任曙砂,我火速辦了婚禮头谜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘麦轰。我一直安慰自己乔夯,他們只是感情好砖织,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布款侵。 她就那樣靜靜地躺著,像睡著了一般侧纯。 火紅的嫁衣襯著肌膚如雪新锈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天眶熬,我揣著相機(jī)與錄音妹笆,去河邊找鬼。 笑死娜氏,一個(gè)胖子當(dāng)著我的面吹牛拳缠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播贸弥,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼窟坐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起哲鸳,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤臣疑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后徙菠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體讯沈,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年婿奔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缺狠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡萍摊,死狀恐怖儒老,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情记餐,我是刑警寧澤驮樊,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站片酝,受9級(jí)特大地震影響囚衔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜雕沿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一练湿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧审轮,春花似錦肥哎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至榴捡,卻和暖如春杈女,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吊圾。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工达椰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人项乒。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓啰劲,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親檀何。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蝇裤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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