kotlin apply run also with let函数

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.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) {
    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.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  run(block: () -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

执行闭包,返回闭包结果

fun main(args: Array) {
    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.also(block: (T) -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block(this)
    return this
}

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

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

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  with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}

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

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

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.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}

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

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

taskIf

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

takeUnless

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

总结

执行非空对象lamda: ?.let
判断局部范围变化: let
对象配置: apply
对象配置和计算处理: run
运行需要的lamda表达式: 非扩展功能 run
附加: also
对象分组调用: with

你可能感兴趣的:(kotlin apply run also with let函数)