254 lines
5.9 KiB
Markdown
254 lines
5.9 KiB
Markdown
---
|
||
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> 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<String>) {
|
||
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, R> 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 <R> run(block: () -> R): R {
|
||
contract {
|
||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||
}
|
||
return block()
|
||
}
|
||
```
|
||
|
||
执行闭包,返回闭包结果
|
||
|
||
```kotlin
|
||
fun main(args: Array<String>) {
|
||
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> T.also(block: (T) -> Unit): T {
|
||
contract {
|
||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||
}
|
||
block(this)
|
||
return this
|
||
}
|
||
```
|
||
|
||
接受一个对象,返回一个对象本身,一般使用于不影响对象本身做某些事
|
||
|
||
```kotlin
|
||
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](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 <T, R> with(receiver: T, block: T.() -> R): R {
|
||
contract {
|
||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||
}
|
||
return receiver.block()
|
||
}
|
||
```
|
||
|
||
非扩展功能,接受一个对象,返回lamda表达式结果,可以理解为 对这个对象执行以下操作
|
||
|
||
```kotlin
|
||
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](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, R> T.let(block: (T) -> R): R {
|
||
contract {
|
||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||
}
|
||
return block(this)
|
||
}
|
||
```
|
||
|
||
接受一个对象,返回lamda表达式结果,或者指定return
|
||
|
||
```kotlin
|
||
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](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
|
||
|