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

254 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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中条件则返回当前值否则返回nullblock的返回值Boolean类型
# takeUnless
不满足block中条件则返回当前值否则返回nullblock的返回值Boolean类型
# 总结
执行非空对象lamda: ?.let
判断局部范围变化: let
对象配置: apply
对象配置和计算处理: run
运行需要的lamda表达式: 非扩展功能 run
附加: also
对象分组调用: with