微信端網(wǎng)站開(kāi)發(fā)流程圖百度收錄入口提交
一、概述
為了幫助您根據(jù)使用場(chǎng)景選擇合適的作用域函數(shù)(scope function),我們將對(duì)它們進(jìn)行詳細(xì)描述并提供使用建議。從技術(shù)上講,許多情況下范圍函數(shù)是可以互換使用的,因此示例中展示了使用它們的約定俗成的做法。
1.let函數(shù)
-
上下文對(duì)象作為參數(shù)(it)提供。
-
返回值:lambda表達(dá)式結(jié)果.
let可以用于在調(diào)用鏈的結(jié)果上調(diào)用一個(gè)或多個(gè)函數(shù)。例如:
var name = "kotlin"
var sub = name.substring(0,2)
println(sub)
用let重寫(xiě)上面的例子,不用分配一個(gè)新的變量就會(huì)直接輸出結(jié)果:
var name = "kotlin"
name.substring(0,2).let {println(it)
}
let代碼塊里,如果只有一個(gè)函數(shù),且函數(shù)只有一個(gè)參數(shù)it,可以用::代替it參數(shù):
var name = "kotlin"
name.substring(0,2).let(::println)
let代碼塊里操作的數(shù)值為非空值,為了操作非空數(shù)值,需要在let前用?.操作符:
val name: String? = null
name?.let {println(it)
}
為了讓代碼更用閱讀可以自定義變量,代替it參數(shù):
val name: String = "kotlin"
val child: String? = name.substring(0, 2)
child?.let { sub ->println(sub)//sub為自定義的變量代替it參數(shù)
}
2.with函數(shù)
-
上下文對(duì)象作為接收者(this)可用。
-
返回值:lambda表達(dá)式結(jié)果.
?with?不是一個(gè)擴(kuò)展函數(shù):上下文對(duì)象this作為參數(shù)傳遞,在lamda表達(dá)式里this可以被當(dāng)作接收者.
當(dāng)不需要返回結(jié)果時(shí),推薦用with時(shí),可以引用上下文對(duì)象調(diào)用方法。例如,
val name = "kotlin"
with(name){println(this)
}
可以在lamda代碼塊里,引用上下文對(duì)象的屬性和函數(shù),例如,
val name = "kotlin"
println("result:${with(name) {length + substring(0, 2).length}}"
)
3.run函數(shù)
-
上下文對(duì)象作為接收者(this)可用。
-
返回值:lamda表達(dá)式結(jié)果
run?跟with作用相同,但run是一個(gè)擴(kuò)展函數(shù)。像let,對(duì)象可以通過(guò)點(diǎn)符號(hào)引用run。當(dāng)lamada表達(dá)式中同時(shí)有初始化和計(jì)算操作,可用run函數(shù)。例如,
class User{var name: String? = nullvar age = 0}User().run {name = "java"age = 99Log.d(TAG,"User:$name,$age")}
你還可以將?run
?作為非擴(kuò)展函數(shù)來(lái)調(diào)用。run
?的非擴(kuò)展版本沒(méi)有上下文對(duì)象,但它仍然返回 lambda 表達(dá)式的結(jié)果。非擴(kuò)展的?run
?允許你在需要表達(dá)式的地方執(zhí)行多個(gè)語(yǔ)句的代碼塊。在代碼中,非擴(kuò)展的?run
?可以理解為“運(yùn)行代碼塊并計(jì)算結(jié)果”。例如,
var name = "c++"name.run {var y = "123"println("$this,$y")}
4.apply函數(shù)
-
上下文對(duì)象作為接收者(this)可用。
-
返回值:this對(duì)象本身.
因?yàn)?apply?函數(shù)返回引用對(duì)象本身,主要用于對(duì)象的成員操作時(shí),可用apply函數(shù)。主要應(yīng)用appply函數(shù)的地方是對(duì)象的配置。對(duì)apply調(diào)用可以被當(dāng)作是對(duì)象的初始化。
class User {var name: String? = nullvar age = 0fun set(ageParam: Int) {age = ageParam}fun get(): Int {return age}}User().apply {name = "java"age = 99set(100)Log.d(TAG, "User:$name,${get()}")}
另一個(gè)?apply
?的使用場(chǎng)景是將其包含在多個(gè)調(diào)用鏈中,以進(jìn)行更復(fù)雜的處理。例如,
class User {var name: String? = nullvar age = 0fun set(ageParam: Int) {age = ageParam}fun get(): Int {return age}}User().apply {name = "java"age = 99set(100)Log.d(TAG, "User:$name,${get()}")}.apply {name = "c++"Log.d(TAG, "User:$name,${get()}")}
5.also函數(shù)
-
上下文對(duì)象作為參數(shù)(it)提供.
-
返回值:引用對(duì)象本身
also?用于操作上下文參數(shù)對(duì)象。引用also的操作都是針對(duì)引用對(duì)象(而不是它的屬性和方法)或者是不想對(duì)外部作用域隱藏this對(duì)象。
常用于鏈?zhǔn)秸{(diào)用中,在不改變對(duì)象的情況下,插入一些中間操作。
當(dāng)看到also時(shí),可以讀作“also跟隨對(duì)象”。
User().also {it.set(100)Log.d(TAG,"also引用,user:${it.age}")}.also {it.set(99)it.name = "kotlin"}.run {Log.d(TAG,"run引用,user:$name, $age")}
二、區(qū)別
1.參數(shù)
自定義參數(shù)it名字:唯獨(dú)let函數(shù)可以自定義參數(shù)it名字
函數(shù)參數(shù)傳遞:唯獨(dú)with函數(shù)把引用對(duì)象作為參數(shù)輸入例如,with(name){}
2.返回值
let,with和run返回值為lamda表達(dá)式結(jié)果,而apply和also返回值為引用對(duì)象本身
3.參數(shù)this和it
參數(shù)為this的函數(shù)為with,run和apply,可直接操作對(duì)象的屬性和方法。
參數(shù)為it的函數(shù)為不能直接操作對(duì)象的屬性和方法。
推薦文章
Scope functions | Kotlin Documentation