--- title: kotlin中的apply run also with let函数 date: 2020-06-08 16:27:10 tags: [kotlin] categories: [kotlin] author: Karl --- # apply ```kotlin /** * 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.apply(block: T.() -> Unit): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } block() return this } ``` 我们从源码中可以知道 apply接受一个对象,返回一个对象。闭包中使用(this)指代对象 一般使用于成员对象的操作 官方文档对其解释为 apply the following assignments to the object. ```kotlin class StudyOne { var karl: String ?= null var karlTwo: String ?= null } ``` ```kotlin fun main(args: Array) { val studyOne = StudyOne().apply { this.karl = "aa" this.karlTwo = "bb" } println("studyOne: ${studyOne.karl}") println("studyOne: ${studyOne.karlTwo}") } //运行结果 //aa //bb ``` 参考文档: [apply](https://kotlinlang.org/docs/reference/scope-functions.html#apply) # run ```kotlin /** * 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.run(block: T.() -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block() } ``` 我们发现 run跟apply的差别只是apply返回对象本身,run一个返回lamda表达式(跟run做同样事情的还有with, let) run一般用于初始化和返回值的计算 ```kotlin fun testRun() { studyOne.run { println("karl") } } // 输出结果 //karl ``` 另一个run 非扩展性功能run ```kotlin @kotlin.internal.InlineOnly public inline fun run(block: () -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block() } ``` 执行闭包,返回闭包结果 ```kotlin fun main(args: Array) { val studyOne = run { StudyOne() } println(studyOne) } //运行结果 //StudyOne@7a81197d ``` 参考文档: [run](https://kotlinlang.org/docs/reference/scope-functions.html#run) # also ```kotlin /** * 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.also(block: (T) -> Unit): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } block(this) return this } ``` 接受一个对象,返回一个对象本身,一般使用于不影响对象本身做某些事 ```kotlin fun main(args: Array) { 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](https://kotlinlang.org/docs/reference/scope-functions.html#also) # with ```kotlin /** * 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 with(receiver: T, block: T.() -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return receiver.block() } ``` 非扩展功能,接受一个对象,返回lamda表达式结果,可以理解为 对这个对象执行以下操作 ```kotlin fun main(args: Array) { val numbers = mutableListOf("one", "two", "three") with(numbers) { this.add("karl") this.add("帅的起飞") } println("numbers: $numbers") } //运行结果 //numbers: [one, two, three, karl, 帅的起飞] ``` 参考文档: [with](https://kotlinlang.org/docs/reference/scope-functions.html#with) # let ```kotlin /** * 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.let(block: (T) -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block(this) } ``` 接受一个对象,返回lamda表达式结果,或者指定return ```kotlin fun main(args: Array) { 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](https://kotlinlang.org/docs/reference/scope-functions.html#let) # taskIf 满足block中条件,则返回当前值,否则返回null,block的返回值Boolean类型 # takeUnless 不满足block中条件,则返回当前值,否则返回null,block的返回值Boolean类型 # 总结 执行非空对象lamda: ?.let 判断局部范围变化: let 对象配置: apply 对象配置和计算处理: run 运行需要的lamda表达式: 非扩展功能 run 附加: also 对象分组调用: with