标准函数let、run、also、all、with、takeIf、takeUnless
Kotlin中,几个常用的标准函数的异同,功能做一个比较和总结。
1、run、with、let、also与apply的区别
重点在于接收者和返回值的不同:
with,T.run,T.apply接收者是 this, T.let和T.also接受者是it;
with,T.run,T.let返回值是作用域的最后一个对象(this),T.apply和T.also返回值是调用者本身(itself)
下面我们就每一个标准函数举例说明。
2、let函数
// let 函数:在作用域内可以对参数it进行操作
// 返回最后一行代码的对象。如果最后一行代码没有返回值(Unit),那么返回kotlin.Unit
val strLet = str.let {
println("let 函数的 it:$it")// it就是变量 str 本身。
it.reversed()// 这里返回 it 经倒序操作之后的对象
}.let {
println("let 函数,经 reversed 操作后的的 it:$it")// it就是前面变量 str 倒序之后的对象。
it.length // 这里返回 it 经倒序操作之后的对象的length长度
}.let {
println("let 函数,经 length 操作后的的 it:$it")// 这里的 it 就是经倒序操作之后的对象的length长度
"reversed"
}
// 上面最后一个 let 函数 最后一行的对象是 "reversed",因此这里 strLet 接收到的值也是 "reversed";
// 如果 没有最后一行的 "reversed" 存在,则 strLet 接收到的返回值是:kotlin.Unit
println("let 函数的 strLet:$strLet")
3、run
// 调用接收者的一系列函数,还可以执行函数引用,也就是调用其他函数
// 多个函数引用可以链式调用,可以执行函数引用
var strRun = str.run(::isLong)
.run(::showTip)
.run(::println)
println("run 函数的 strRun 01:$strRun")
// 调用接收者的一系列函数,还可以执行函数引用,也就是调用其他函数
strRun = str.run {
this.substring(5)
}
// run函数的返回值类型是:kotlin.Unit,因此,无论 run函数的最后一行是什么类型的操作,都不会改变返回值结果。
println("run 函数的 strRun 02:$strRun")
4、also
// public inline fun <T> T.also(block: (T) -> Unit): T
// 什么类型的变量调用 also 函数,就返回这个变量本身,
// 无论 also 函数内部对该变量做了什么操作,或者also函数最后一行是什么操作
// 需要把接收者值参传给lambda,但also返回接收者对象。
// also尤其适合针对同一原始对象,可以基于原始接收者对象执行额外的链式调用
val strAlso = str.also {
println("also 函数的 it:$it")
}
println("also 函数的 strAlso:$strAlso")
5、apply
// public inline fun <T> T.apply(block: T.() -> Unit): T
// 调用当前对象的一系列函数。和 also函数 类似,什么类型的变量调用 apply 函数,就返回这个变量本身.
// apply能让每个配置函数都作用于接收者
val strApply = str.apply {
this.length * this.length
}
println("apply 函数的 strApply:$strApply")
6、all
// 会返回一个boolean值,因此,all 函数的最后一行,都是一个 Boolean 类型的操作或者变量
val strAll = str.all {
println("all 函数的 it:$it")
it.equals("")
}
println("all 函数的 strAll:$strAll")
7、with
// run函数的变体,功能行为一样,with的调用方式不同,with需要值参作为其第一个参数传入
// with函数 会返回最后一行的结果,最后一行是 某种具体类型的对象,就返回这个对象,如果不是具体对象,就返回 kotlin.Unit
// 就如下面,如果最后一行是“length>=3”,就返回 Boolean值;
// 如果最后一行是 substring()操作,就返回 str 经 substring()操作 后的字符串;
// 如果最后一行是 println()或者其他没有返回值的操作,那么就返回 kotlin.Unit。
val strWith = with(str){
length>=3
this.substring(5)
println("with 函数的 str:$str")
}
println("with 函数的 strWith:$strWith")
8、takeIf、takeUnless
// TODO:takeif函数需要判断lambda中提供的条件表达式的结果,如果是true,takeif函数返回接收者对象,
// 如果是false,返回Null。
// TODO:如果需要判断某个条件是否满足,再决定是否可以赋值变量或执行某项任务,takeif就非常有用。
val strTakeIf = str.takeIf {
it.contains("j")
}?.substring(2, 6)// {} 中的条件为true,才会执行后面的 substring()逻辑。
println("takeIf 函数的 strTakeIf:$strTakeIf")
// TODO: takeUnless与takeif的返回结果情况相反,返回为false才会返回
val strTakeUnless = str.takeUnless {
it.contains("Z")
}?.substring(2, 6)// {} 中的条件为false,才会执行后面的 substring()逻辑。
println("takeUnless 函数的 strTakeUnless:$strTakeUnless")