選擇哪種函數(shù)
1.讓我們看看源碼中是如何定義的
/**
* Calls the specified function [block] and returns its result.
*/
@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
/**
* Calls the specified function [block] with `this` value as its receiver and returns its result.
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
/**
* Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return receiver.block()
}
/**
* Calls the specified function [block] with `this` value as its receiver and returns `this` value.
*/
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
/**
* Calls the specified function [block] with `this` value as its argument and returns `this` value.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
/**
* Calls the specified function [block] with `this` value as its argument and returns its result.
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
看每個(gè)方法的返回值類型
apply,also返回的是它本身類型
run嘀倒,with屈留,let返回的是代碼塊最后一行的返回值類型
2.各個(gè)函數(shù)的應(yīng)用場景
2.1 T.apply應(yīng)用場景
//普通方法
fun createIntent(): Intent {
val intent = Intent()
intent.putExtra("nameFirst", "firstValue")
intent.putExtra("nameSecond", "secondValue")
return intent
}
//通過apply函數(shù)
fun createIntentByApply(): Intent =
Intent().apply {
putExtra("nameFirst", "firstValue")
putExtra("nameSecond", "secondValue")
}
//通過apply函數(shù)鏈?zhǔn)秸{(diào)用
fun createIntentByChainedApply(): Intent =
Intent().apply { putExtra("nameFirst", "firstValue") }
.apply { putExtra("nameSecond", "secondValue") }
2.2 T.also函數(shù)
"abc".also {
print("The String is $it") // "abc"
it.reversed()
}.also {
print("The reverse String is $it") // "abc"
it.length
}.also {
println("The length of the String is $it") // "abc"
}
2.3 T.let函數(shù)
"abc".let {
println("The String is $it") // "abc"
it.reversed()
}.let {
println("The reverse String is $it") // "cba"
it.length
}.let {
println("The length of the String is $it") // 3
}
和also函數(shù)相比返回值不同局冰,T.let返回的是作用域最后一個(gè)對(duì)象(可和自身對(duì)象不同),
T.also返回的都是原來自身對(duì)象灌危。
兩者結(jié)合使用場景
//原始函數(shù)
fun makeDir(path: String): File {
val result = File(path)
result.mkdirs()
return result
}
//通過let和also的鏈?zhǔn)秸{(diào)用改進(jìn)后的函數(shù)
fun makeDir(path: String) = path.let{ File(it) }.also{ it.mkdirs() }
2.4 run函數(shù)使用場景
run {
if (islogin) loginDialog else getAwardDialog
}.show()
2.5 with函數(shù)使用場景
with(webView.settings){
javaScriptEnabled = true
databaseEnabled = true
}
2.6 T.run函數(shù)使用場景
//此時(shí)run函數(shù)比上面例子要更好康二,因?yàn)樵谡{(diào)用函數(shù)之前進(jìn)行null檢查
webView.settings?.run {
javaScriptEnabled = true
databaseEnabled = true
}