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