如何选择Kotlin作用域函数-let,run,with,apply
文章目录
如何选择这些作用域函数
在 Kotlin 开发中,经常使用到let
,apply
,also
,run
等一些作用域函数,具体什么是作用域函数,可以看下官网地址作用域函数,这里不在展开讲,不明白的可以看下官方文档。
我们在实际使用中,你会是否会有这样的疑惑,到底 使用那个作用域函数,好像有些情况,每个都可以。有 些情况,又只能用特定的函数?
其实要弄明白这些,就需要弄明白这些函数的特点。而要区分这些函数的差异,我们可以从三个维度来进行区分,分别是:是否是扩展函数、返回值差异、参数是什么。可以看下下面的表格:
函数 | 对应引用方式 | 返回值 | 是否是扩展函数 |
---|---|---|---|
let |
it |
Lambda result | Yes |
run |
this |
Lambda result | Yes |
run |
- | Lambda result | No: called without the context object |
with |
this |
Lambda result | No: takes the context object as an argument. |
apply |
this |
Context object | Yes |
also |
it |
Context object | Yes |
上面的表格是官网中的表格,列举了各个函数在各个维度的差异。但是看起来还是觉得不够直观,所以这里我做一个选择使用那个函数的 “抉择图”,可以看下
所以下次不知道用哪个,就可以照着这个图选就行了~~~
使用问题
现在 kotlin 基本上是开发的主力语言,开发中也是大量使用到作用域函数。但是使用作用域函数的时候,碰到了一些比较典型问题。这些问题在 review 其他人代码时也会看到,说明大家可能都碰到了这些问题,这里选取最常见的两个进行说明。
1、过多嵌套使用
经常看到代码中有很多嵌套使用作用域函数的场景,举个例子:
|
|
从上面的代码可以看到,如果过多使用嵌套作用域函数,就会形成类似“回调地狱”的代码形式
,再加上代码中还用到了一些lambdas
,情形更加严重,导致代码极其难看。在我们的项目中,经常看到类似的代码。那么有什么办法改善呢?
我认为有如下几个方法:
- 一个是把代码进行抽离,放到不同的函数中,减少嵌套
- 很多情况都是为了判空,我们可以提前做空判断,或者定义
Contract
,后续的该变量都是用非空状态,这样就不用到处判断,减少嵌套
2、参数 this/it、引用混淆
有些作用域函数是有参数传递的,有些是 this,有些是 it,而如果嵌套使用,就会出现代码可读性的问题,甚至引起错误,举几个例子:
第一个例子:
|
|
上面代码,可以看到有三个 it,到底是那个是哪个,有时候并不一定好区分。同样其他参数是 it 的作用域函数也有这个问题。
第二个例子:
|
|
上面代码中,apply
方法里面。Widget
的width、name
和Style
的同名,有时候就无法分辨清楚,甚至报错。 这些情况该怎么处理呢?
- 不要使用默认的命名,比如 it,尽量重命名有意义的名字
- 不要大量嵌套使用作用域函数
像
apply
这种没有办法重命名参数的作用域函数,在引用变量的时候,可以借助label
标签,比如上面apply
的例子1 2 3 4 5 6 7 8 9 10 11 12 13 14
class Widget(val name: String, val width: Double) { val style: Style init { val height = width * 1.5 style = Style().apply { // 使用标签 this.width = this@Widget.width this.height = height this.name = this@Widget.name } } }
文章作者 卒子行
上次更新 2023-09-12