常见标准函数with,run,apply,let
- 前言
- 标准函数
- with函数
- run函数
- apply函数
- let函数
抓住今天,尽可能少的信赖明天。 喝汤能补 (* ^ ▽ ^ *)
前言
该文章作为学习交流,如有错误欢迎各位大佬指正 (* ^ ▽ ^ *)
- 自身技能
(1)已具备计算机的基本知识
(2)了解Lambda语法 - 本文简介
主要讲解:关于标准函数库中with,run,apply,let函数的用法。
标准函数
Kotlin的标准函数指的是Standard.kt文件中定义的函数,任何Kotlin代码都可以自由地调用所有的标准函数。
小结
- 表达式中提供第一个参数对象的上下文:简单理解,在该表达式中,可以像在参数对象的类中一样,直接调用类中的方法,不需要使用 对象.funxx() 的方式进行调用。
- with,run,apply这几个函数的用法非常类似,但我们要能知道他们的差异,并在编程中选择最佳的函数。
with与run与apply
区别 | 参数 | 是否可直接调用 | 是否能以Lambda表达式作为返回值 |
with | 两个参数 任意对象,Lambda表达式 | 是 | 是 |
run | 一个参数 Lambda表达式 | 否 需对象调用 | 是 |
run | 一个参数 Lambda表达式 | 否 需对象调用 | 否 返回调用对象本身 |
with函数
with函数接收两个参数:第一个参数可以是任意类型的对象,第二个参数是一个Lambda表达式。with函数会在Lambda表达式中提供第一个参数对象的上下文, 且使用Lambda表达式中最后一行代码作为返回值返回。
// 基本语法
val result = with(obj){
// 这里是obj的上下文
"value" //with函数的返回值
}
简单示例
val list = listOf("A", "B", "C", "D", "E", "F")
val result = with(StringBuilder()) {
append(" Connect them together \n")
for (word in list) {
append(word).append(" ")
}
append(" no word ")
}
println(result)
run函数
run函数用法与with函数类似,语法上有点差异。无法直接调用run函数,必须某个对象调用run函数才行;run函数只接受一个Lambda参数,也会在Lambda表达式中提供调用对象的上下文, 以及使用Lambda表达式中最后一行代码作为返回值返回。
// 基本语法
val result = obj.run(){
// 这里是obj的上下文
"value" //with函数的返回值
}
简单示例
val list = listOf("A", "B", "C", "D", "E", "F")
val result = StringBuilder().run() {
append(" Connect them together \n")
for (word in list) {
append(word).append(" ")
}
append(" no word ")
}
println(result)
apply函数
apply函数与run函数类似,必须某个对象调用apply函数;apply函数只接受一个Lambda参数,也会在Lambda表达式中提供调用对象的上下文。
差异点在于:apply函数无法指定返回值,而是自动返回调用对象本身。
// 基本语法
val result = obj.apply(){
// 这里是obj的上下文
}
// return == obj
简单示例
val list = listOf("A", "B", "C", "D", "E", "F")
val result = StringBuilder().apply() {
append(" Connect them together \n")
for (word in list) {
append(word).append(" ")
}
append(" no word ")
}
println(result.toString())
let函数
这个函数将原始调用对象作为参数传递到Lambda表达式中。
将obj对象传递到lambda表达式中,参数名为obj2,但obj与obj2 是同一个对象。
- let可以用来处理全局变量为空判断,而if则不行,因为无法保证if语句中的全局变量不被其他线程所修改。
val obj=""
obj.let {
obj2 ->
//编写具体的业务
}
使用let与?.更加简化为空判断
fun useFun1(an: Animal?){
an?.eat()
an?.say()
}
// 优化
fun useFun2(an: Animal?){
an?.let {
a ->
a.say()
a.eat()
}
}
// 上篇说的,只有一个参数,可以使用it
an?.let {
it.say()
it.eat()
}
// 无法编译通过
var animal :Animal? = null
fun useFun3(an: Animal?){
if (animal != null){
animal.say() //还是报错,animal可能被其他线程修改成null
animal.eat()
}
}