kotlin
作用域函数
含义:Kotlin中对一个对象进行一系列操作的函数,写法上类似集合的操作符
种类:、、、、、、、
第一类:有返回结果的
举例:通过和函数输入一段话,和函数都是将参数中闭包的返回值当做自己的返回值给返回出来,具体看源码实现。
// 都是有返回结果,但是let闭包有参数,可以用it指代对象
// run没有闭包参数的,只能用this来指代对象
valletResult = user.let {"let::{$}"}
println(letResult)
// let::
valrunResult = user.run {"run::{$}"}
println(runResult)
// run::
和的源码:
通过源码可以看出,参数是有返回值的。同理。但是中是将继续以参数的形式传给了闭包,所以在闭包中可以使用来代替对象,而却只能用关键字。
第二类:无返回结果
举例:同样是通过和输出一句话,但是没有返回的是对象,不是闭包函数。具体看下面源码实现。
// also、apply和let、run的区别在于闭包内的操作没有返回结果
// also和let一致,有闭包参数,可以使用it
// apply和run一致,没有闭包参数,只能使用this
user.also {
println("also::{$}")
}
// also::
user.apply {
println("apply::{$}")
}
// apply::
源码:
// also
kotlin
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
publicinlinefunT.also(block: (T)->Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
returnthis
}
// apply
@kotlin.internal.InlineOnly
publicinlinefunT.apply(block:T.()->Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
returnthis
}
从的源码一眼就能看到,参数返回了一个,函数是将调用者给返回了。同理。和解释看上面和的解释。
第三类:函数的闭包有返回值,但是为Boolean类型
举例:通过和函数中的闭包结果进行判断,然后做出相应的操作。其中闭包返回值都为Boolean类型。
// takeIf和takeUnless的闭包参数都会返回一个Boolean类型的值
// takeIf内闭包为false时,taleIf执行完会返回一个null
// takeUnless内闭包为true时,takeUnless执行完会返回一个null,和takeIf正好相反
user.takeIf { it.name.isNotEmpty() }
?.also { println("name is {$}") }
?: println("name is null")
user.takeUnless { it.name.isNotEmpty() }
?.also { println("name is null") }
?: println("name is {$}")
源码:
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
publicinlinefunT.takeIf(predicate: (T)->Boolean): T? {
contract {
callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
}
returnif(predicate(this))thiselsenull
}
通过上面的源码可以看出,如果闭包的返回值为,那么函数就会返回一个。
正好与之相反。
第四类:循环执行函数
repeat(2) {
println("count is$it,name is$")
}
// count is 0,name is taonce
// count is 1,name is taonce
函数不仅仅用于集合中,它的适用范围是任意对象,需要传入两个参数:,是循环的次数,就是闭包。通过上面的例子就能知道,闭包的执行次数有确定。
第五类:顶层函数
with(user) {
this.name ="kotlin"
println("user name is$")
}
// user name is kotlin
比较特殊,它不是通过对象调用使用的,而是把对象作为参数传入的。适用场景,对同一个对象进行相同的操作。比如一个和一个都需要显示文字内容为开始,就可以用同步操作:
with(view) {
this.text ="开始"
}
只需要这么写就可以完全同意处理了。
也是有返回值的,它和、很像,最大的不同在于的参数,可以对同一类型的对象进行相同的操作,比如上面对和的操作,如果换做是和就不行了,因为它们是通过对象调用的方法。
写在最后
每个人不是天生就强大,你若不努力,如何证明自己,加油!
Thank You!
--Taonce
如果你觉得这篇文章对你有所帮助,那么就动动小手指,扫描下方的二维码,关注一波吧~~非常期待大家的加入
领取专属 10元无门槛券
私享最新 技术干货