let
定義:默認當前這個對象作爲閉包的it參數,返回值是函數裏面最後一行,或者指定return
源碼
/**
* Calls the specified function [block] with `this` value as its argument and returns its result.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#let).
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
使用: 判斷對象是否爲空,使代碼看起來更加優美
package `fun`
class test {
var count: Int = 0
fun funtion() {
println("run funtion $count")
count++
}
}
fun main(args:Array<String>) {
// 不使用 let 判空
val tmp = test()
if (tmp != null) {
tmp?.funtion()
tmp?.funtion()
tmp?.funtion()
}
// 使用let
tmp.let {
it.funtion()
it.funtion()
it.funtion()
}
}
also
類似let函數,但區別在於返回值:
let函數:返回值 = 最後一行 / return的表達式
also函數:返回值 = 傳入的對象的本身
源碼
/**
* Calls the specified function [block] with `this` value as its argument and returns `this` value.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#also).
*/
@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
}
- 使用
package `fun`
class also_test {
var count: Int = 0
fun funtion() {
println("run also funtion $count")
count++
}
}
fun main(args:Array<String>) {
val tmp = also_test()
// 使用let
val result_let = tmp.let {
it.funtion()
it.funtion()
it.funtion()
"hello let"
}
println(result_let)
// 使用also
val result_also = tmp.also {
it.funtion()
it.funtion()
it.funtion()
"hello also"
}
println(result_also)
}
輸出
apply
與run函數類似,但區別在於返回值:
run函數返回最後一行的值 / 表達式
T.() : 代表自身的對象來調用它
(T) : 某一個對象的調用
源碼
/**
* Calls the specified function [block] with `this` value as its receiver and returns `this` value.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#apply).
*/
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
使用
// 改寫apply函數
public inline fun <T> T.apply1(block: T.() -> Unit): T {
return this
}
public inline fun <T> T.apply2(block: (T) -> Unit): T {
return this
}
anyObject.apply1 { // this: MutableList<String>
add("addObject")
}
anyObject.apply2 { // it: MutableList<String>
it.add("addObject")
}
with
調用同一個對象的多個方法 / 屬性時,可以省去對象名重複,直接調用方法名 / 屬性即可
源碼
/**
* Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#with).
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return receiver.block()
}
使用:需要調用同一個對象的多個方法 / 屬性
with(object){
// ...
}
// 返回值 = 函數塊的最後一行 / return表達式
run
結合了let、with兩個函數的作用,即:
調用同一個對象的多個方法 / 屬性時,可以省去對象名重複,直接調用方法名 / 屬性即可
定義一個變量在特定作用域內
統一做判空處理
源碼
/**
* Calls the specified function [block] and returns its result.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#run).
*/
@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
使用:
object.run{
// ...
}
// 返回值 = 函數塊的最後一行 / return表達式
takeif
源碼
/**
* Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
contract {
callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
}
return if (predicate(this)) this else null
}
從源碼可以看出來:它是從T對象本身調用的。即T.takeIf,
predicate函數以T對象爲參數
等待predicate評估後它返回this或null