解析Kotlin:let ,apply,run,with,also,takeif

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)
}

输出
解析Kotlin:let ,apply,run,with,also,takeif_第1张图片

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
    add("addObject")
}

anyObject.apply2 {  // it: MutableList
    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

你可能感兴趣的:(Kotlin)