• Kotlin的作用域函数 let、also、with、run、apply


    作用域函数主要有下面这几种,apply ,with  、run 、let 、以及 also 。这些函数非常类似,它们的主要区别:

    • 引⽤上下⽂对象的⽅式 (this / it)
    • 返回值

    他们在开发中的使用场景主要有两个,一是非空判断,二是对象的初始化或者本身及方法的频繁调用

    let函数上下⽂对象作为 lambda 表达式的参数( it )来访问。返回值是 lambda 表达式的结果。 let 可⽤于在调⽤链的结果上调⽤⼀个或多个函数

    1. public inline fun T.let(block: (T) -> R): R {
    2. contract {
    3. callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    4. }
    5. return block(this)
    6. }

    also函数 上下⽂对象作为 lambda 表达式的参数( it )来访问。返回值是上下⽂对象本⾝。 also 对于执⾏⼀些将上下⽂对象作为参数的操作很有⽤。对于需要引⽤对象⽽不是其属性与函数的 操作,或者不想屏蔽来⾃外部作⽤域的 this 引⽤时,请使⽤ also 。 当你在代码中看到 also 时,可以将其理解为“并且⽤该对象执⾏以下操作”。

    1. public inline fun T.also(block: (T) -> Unit): T {
    2. contract {
    3. callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    4. }
    5. block(this)
    6. return this
    7. }

    with函数 ⼀个⾮扩展函数:上下⽂对象作为参数传递,但是在 lambda 表达式内部,它可以作为接收者( this )使 ⽤。返回值是 lambda 表达式结果。 我们建议使⽤ with 来调⽤上下⽂对象上的函数,⽽不使⽤ lambda 表达式结果。在代码中,with 可 以理解为“对于这个对象,执⾏以下操作。”

    1. public inline fun with(receiver: T, block: T.() -> R): R {
    2. contract {
    3. callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    4. }
    5. return receiver.block()
    6. }

    run函数 上下⽂对象 作为接收者( this )来访问。返回值 是 lambda 表达式结果 当 lambda 表达式同时包含对象初始化和返回值的计算时,run 很有⽤。

    1. public inline fun T.run(block: T.() -> R): R {
    2. contract {
    3. callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    4. }
    5. return block()
    6. }

    apply函数 上下⽂对象 作为接收者( this )来访问。返回值 是上下⽂对象本⾝。 对于不返回值且主要在接收者( this )对象的成员上运⾏的代码块使⽤ apply 。apply 的常⻅情况 是对象配置。这样的调⽤可以理解为“将以下赋值操作应⽤于对象”。

    1. public inline fun T.apply(block: T.() -> Unit): T {
    2. contract {
    3. callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    4. }
    5. block()
    6. return this
    7. }

    根据返回结果,作⽤域函数可以分为以下两类:

    • apply 及 also 返回上下⽂对象。
    • let 、run 及 with 返回 lambda 表达式结果.

    apply 及 also 的返回值是上下⽂对象本⾝。因此,它们可以作为辅助步骤包含在调⽤链中:你可以 继续在同⼀个对象上进⾏链式函数调⽤。

    Lambda 表达式结果

    let 、run 及 with 返回 lambda 表达式的结果。所以,在需要使⽤其结果给⼀个变量赋值,或者在需 要对其结果进⾏链式操作等情况下,可以使⽤它们。

    介绍下lambda表达式

    lambda表达式实际上有两种形式,一种是基本形式,还有一种是带接收者的形式,两种lambda表达式如下所示:

    普通lambda表达式:{ () -> R }  ,                            即函数无入参,返回值为R类型。

    带接收者的lambda表达式:{ T.() -> R }                    即申明一个T类型的接收者对象,且无入参,返回值为R类型。

    Kotlin中的拓展函数,实际上就是使用的带接收者的lambda表达式,

    带接收者的lambda与普通的lambda的区别主要在于this的指向区别,T.() -> R里的this代表的是T的自身实例,而() -> R里,this代表的是外部类的实例。

  • 相关阅读:
    DDD - 一文读懂DDD领域驱动设计
    数据结构排序算法---八大排序复杂度及代码实现
    C#神器"BlockingCollection"类实现C#神仙操作
    PYTHON用户流失数据挖掘:建立逻辑回归、XGBOOST、随机森林、决策树、支持向量机、朴素贝叶斯和KMEANS聚类用户画像...
    香橙派Zero3安装miniconda3(问题多多,已全部解决)
    注册商标的重要性
    如何在Linux搭建MinIO服务并实现无公网ip远程访问内网管理界面
    Java 字节流写数据加异常处理之finally的用法
    Java开发篇——设计模式(2)单例模式你真的了解吗?(下)
    ABP框架入门
  • 原文地址:https://blog.csdn.net/nuonuonuonuonuo/article/details/133752749