blog/docs/code/kotlin/kotlin-func.md

5.9 KiB
Raw Blame History

title date tags categories author
kotlin中的apply run also with let函数 2020-06-08 16:27:10
kotlin
kotlin
Karl

apply

/**
 * 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接受一个对象返回一个对象。闭包中使用(this)指代对象

一般使用于成员对象的操作

官方文档对其解释为 apply the following assignments to the object.

class StudyOne {
    var karl: String ?= null

    var karlTwo: String ?= null
}
fun main(args: Array<String>) {
    val studyOne = StudyOne().apply {
        this.karl = "aa"
        this.karlTwo = "bb"
    }
    println("studyOne: ${studyOne.karl}") 
    println("studyOne: ${studyOne.karlTwo}")
}
//运行结果
//aa
//bb

参考文档: apply

run

/**
 * Calls the specified function [block] with `this` value 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#run).
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

我们发现 run跟apply的差别只是apply返回对象本身run一个返回lamda表达式(跟run做同样事情的还有with, let)

run一般用于初始化和返回值的计算

fun testRun() {
  studyOne.run {
        println("karl")
    }
}
// 输出结果
//karl

另一个run 非扩展性功能run

@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

执行闭包,返回闭包结果

fun main(args: Array<String>) {
    val studyOne = run {
            StudyOne()
        }
    println(studyOne)
}
//运行结果
//StudyOne@7a81197d

参考文档: run

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
}

接受一个对象,返回一个对象本身,一般使用于不影响对象本身做某些事

fun main(args: Array<String>) {
    val numbers = mutableListOf("one", "two", "three")
    val alsoTest = numbers.also {
        println("kotlin真好用")
        println("c: $it")
    }
        .add("four")
    println("c: $numbers")
}
//运行结果
//kotlin真好用
//c: [one, two, three]
//c: [one, two, three, four]

参考文档: also

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

非扩展功能接受一个对象返回lamda表达式结果可以理解为 对这个对象执行以下操作

fun main(args: Array<String>) {
    val numbers = mutableListOf("one", "two", "three")
    with(numbers) {
        this.add("karl")
        this.add("帅的起飞")
    }
    println("numbers: $numbers")
}
//运行结果
//numbers: [one, two, three, karl, 帅的起飞]

参考文档: with

let

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

接受一个对象返回lamda表达式结果,或者指定return

fun main(args: Array<String>) {
    val numbers = mutableListOf("one", "two", "three")
    fun testLet(): Int {
        numbers.let {
            return if (Random().nextBoolean()) {
                it.add("five")
                println(it)
                1
            } else {
                it.add("six")
                println(it)
                2
            }
        }
    }
}

?.let 对象不为空时执行

参考文档: let

taskIf

满足block中条件则返回当前值否则返回nullblock的返回值Boolean类型

takeUnless

不满足block中条件则返回当前值否则返回nullblock的返回值Boolean类型

总结

执行非空对象lamda: ?.let

判断局部范围变化: let

对象配置: apply

对象配置和计算处理: run

运行需要的lamda表达式: 非扩展功能 run

附加: also

对象分组调用: with