阅读 185

Kotlin作用域函数及用法

前言

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

以上是官网对Kotlin作用域的一个解释,读几遍是不是也不懂他意思?

从实际出发,依次展开来看看。

let

在作用域中使用(it)来访问对象,返回值是lambda 表达式的结果。

fun main() {     var name="name"     println(name.let {         it.length     }) } 复制代码

如上操作,在{}号中,有个隐式的变量名it,在其中对name变量的任何操作都可以使用it来代替,如果在其中更改了对象的值,那么it变量是不会发生改变的。

并且最后一行的返回结果,会作为let函数的返回结果。如果最后一行没有返回值,在Kotlin中也会被kotlin.Unit来代替。

run

在作用域中使用(this)来访问对象,返回值是lambda 表达式的结果。

fun main() {     var name="name"     println(name.run {         println(length)         "a"     }) } 复制代码

如上操作,除了返回值和let一样,他的作用域变量成为了this,但是这里就发生了一个变化,对对象的操作可以不加this,直接可以调用,而let中不行,比如上面的操作,如果用let来访问length方法时,就必须是it.length,在看一个例子,

class Data(var name: String) { } fun main() {     var name = "name"     println(Data("dog").run {         println(name)         name="cat"     })     println(name) } 复制代码

run还有一个非扩展方法,调用也不需要什么参数,返回值Lambda 表达式结果,如下。

fun main() {     var function = {         println("a")     } //    function()     run(function) } 复制代码

在Java中,方法中写的{}会自动执行,而kotlin不会,需要手动调用,或者是run。

with

他不是扩展函数,也就是没有obj.with这种写法,而是with(obj){},然后在lambda表达式内部,可以使用(this)访问此对象,也可以省略, 返回值是lambda 表达式结果。

with可以理解为"对于这个对象,执行以下操作"。

var name="cat" with(name){     name="dog"     println(name)     println(this) } 复制代码

同样,在作用域中对原对象修改后,并不影响其中的this。

apply

在作用域中使用(this)来访问对象,返回值是是对象本身。

class Data(var name: String) { } fun main() {     var name = Data("dog").apply {         name = "cat"     }     println(name.name) } 复制代码

also

在作用域中使用(it)来访问对象,返回值是是对象本身。

class Data(var name: String) { } fun main() {     var name = Data("dog").also {        it.name="cat"     }     println(name.name) } 复制代码

总结

看了这么多,是不是还迷迷糊糊的,这些作用域函数都非常相似,因此了解它们之间的区别很重要,我们可以从他们这两点区分。

  • 引用上下文对象的方式

  • 返回值

函数对象引用返回值是否是扩展函数
letitLambda 表达式结果
alsoit上下文对象mps
runthisLambda 表达式结果
withthisLambda 表达式结果不是:把上下文对象当做参数
applythis上下文对象
run-Lambda 表达式结果不是:调用无需上下文对象

最重要的就是记住返回值,因为对象引用的方式不太重要,如果你想少写代码,并且返回值需要Lambda 表达式结果,那么就使用run,如果需要本身,那就使用apply。

我们在看一个例子。

public class MainJava {     public static void main(String[] args) throws IOException {         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("/home/HouXinLin/1.txt")));         String temp = null;         while ((temp = bufferedReader.readLine()) != null) {             System.out.println(temp);         }     } } 复制代码

而在Kotlin中while中又赋值又判断这种写法是错的,解决方式就需要使用作用域函数,并且接收的变量还需要设置为可空类型

fun main() {     var bufferedReader = File("/home/HouXinLin/1.txt").inputStream().bufferedReader()     var temp: String?     while (bufferedReader.readLine().also { temp = it } != null) {         println(temp)     } }


作者:i听风逝夜
链接:https://juejin.cn/post/7048596405119778846

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐