Kotlin-作用域函数

一:概念

Kotlin 标准库包含几个函数,它们的唯一目的是在对象的上下文中执行代码块。当对一个对象调用这样的函数并提供一个 lambda 表达式时,它会形成一个临时作用域。在此作用域中,可以访问该对象而无需其名称。这些函数称为作用域函数。共有以下五种:letrunwithapply 以及 also

这些函数基本上做了同样的事情:在一个对象上执行一个代码块。不同的是这个对象在块中如何使用,以及整个表达式的结果是什么。

先来看下如果不用作用域函数,我们平常是怎么在进行处理代码的。

   val alice = PersonMen("Alice", 20, "Amsterdam")
   alice.age=16
   alice.gj="Ydl"

通过作用域函数let看下是怎么调用的:

  PersonMen("Alice", 20, "Amsterdam").let {
       it.age=30
       it.gj="London"
   }

可见使用了let函数,形成一个临时的作用域。在此作用域中,可以访问该对象而无需其名称。

 

二:5个作用域函数的区别和相处

        以下的表格是对五个作用域函数的对比

作用域函数上下文对象返回结果类型是否能单独使用
letit(可自定义)lambda表达式的最后一行是返回值
alsoit(可自定义)T的类型(上下文对象)
runthis(可隐式地访问对象)lambda表达式的最后一行是返回值
applythis(可隐式地访问对象)T的类型(上下文对象)
withthis(可隐式地访问对象)lambda表达式的最后一行是返回值

1:上下文对象

     var str: String= "Hello"

           str.let {
                println("let() called on $it")
            }

            str.also {
                println("also() called on $it")
            }

            str.run {
                println("run() called on $this")
            }

            str.apply {
                println("apply() called on $this")
            }

            with(str) {
                println("with() called on $this")
            }

输出结果

let()   called on Hello
also()  called on Hello
run()   called on Hello
apply() called on Hello
with()  called on Hello
  • this可隐式地访问对象,it不能
     str.let {
        it.length
      }

     str.run {
        this.length
        length
     }

从以上代码可知,this省略也可以直接调用length,但是如果it省略直接写 length ,代码是会报错

  • it作为上下文可进行自定义这个上下文的名字
 str.let {value->
     value.length
 }

代码中定义value为上下文,但是this则不可以

2:返回结果类型

 var list: MutableList<String> = mutableListOf<String>()
  list.add("b")
  var letResult = list.let {
    it.add("a")
   }

  println("let() called on $letResult")
  println("let() called on $list")

结果:

let() called on true
let() called on [b, a]

可以看出let函数返回结果是:lambda表达式的最后一行的值

换成also函数:

  var list: MutableList<String> = mutableListOf<String>()
   list.add("b")
   var letResult = list.also {
   it.add("a")
   }

    println("also() called on $letResult")
    println("also() called on $list")

输出结果:

also() called on [b, a]
also() called on [b, a]

可以看出also函数返回结果是:T的类型(上下文对象)

3.是否能单独使用

这个在我的理解是是否一定要跟在"."的后面,这样就限制了函数的使用位置,五种函数中不同的是with函数,with 可以理解为“对于这个对象,执行以下操作。

 with(str) {
    println("with() called on $this")
 }

三:函数选择

以下是根据预期目的选择作用域函数的简短指南:

  • 对一个非空(non-null)对象执行 lambda 表达式:let
  • 将表达式作为变量引入为局部作用域中:let
  • 对象配置:apply
  • 对象配置并且计算结果:run
  • 在需要表达式的地方运行语句:非扩展的 run
  • 附加效果:also
  • 一个对象的一组函数调用:with

不同函数的使用场景存在重叠,你可以根据项目或团队中使用的特定约定选择函数。

尽管作用域函数是使代码更简洁的一种方法,但请避免过度使用它们:这会降低代码的可读性并可能导致错误。避免嵌套作用域函数,同时链式调用它们时要小心:此时很容易对当前上下文对象及 this 或 it 的值感到困惑。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kotlin协程的作用域函数有五种:letrun、with、apply以及also。这些函数基本上做了同样的事情:在一个对象上执行一个代码块。例如,我们可以使用apply函数来初始化一个对象的属性,如下所示:val adam = Person("Adam").apply { age = 20 city = ... }。通过apply函数,我们可以在代码块内直接访问和修改对象的属性,从而简化了对象的初始化过程。 在使用协程的过程中,如果我们想要判断协程是否被取消了,根据不同的情况采取相应的处理逻辑,可以使用if语句和isActive属性来判断。但是这样做可能比较繁琐且容易出错。另一种更简洁的方式是使用yield函数,yield函数是官方协程框架提供的一个对逻辑没有影响的挂起函数。通过使用yield函数,我们可以在协程中暂停执行,并且不需要关心协程的取消状态。 除了官方提供的几种作用域函数外,我们还可以通过继承或组合的方式创建自定义的协程作用域。例如,在ViewModel或Service中,我们可以使用SupervisorJob来创建自己的CoroutineScope对象。通过自定义的协程作用域,我们可以管理和控制协程的生命周期,并且可以处理协程中可能发生的异常。比如,在ViewModel中,我们可以在onCleared方法中取消自定义的协程作用域,确保协程的正确关闭。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Kotlin作用域函数之间的区别和使用场景详解](https://download.csdn.net/download/weixin_38690830/14014853)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【深入理解Kotlin协程】协程作用域、启动模式、调度器、异常和取消【使用篇】](https://blog.csdn.net/lyabc123456/article/details/127800121)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值