1 let
使用场景:对象非空判断处理,当一个对象不为空时,去对该对象做处理,反之不处理;像Java中的 if(a == null)就可以使用let代替
val res: String? = null
val newString = res?.let {
it + "123"
}
let会判断res是否为空,如果不为空,可以执行let里面的lambda表达式,从而输出新的字符串
2 with
使用场景:调用同一类的多个方法时,可以将该类作为接受者receiver,lambda表达式中,可以直接调用该类的方法
var user1 = User("kk", 13)
with(user1,{
println("用户名$name 年龄$age")
})
这种情况下不用调用user1.name去获取name属性,可以直接调用user1的getName方法
除此之外,在ListView或者RecyclerView中,绑定Item数据时,经常调用一个对象的很多方法,这种也可以通过with实现
override fun onBindViewHolder(holder: MineViewHolder, position: Int) {
with(data.get(position),{
holder.tv_title.text = this
holder.tv_info.text = this
})
// holder.tv_title.text = data.get(position)
// holder.tv_info.text = data.get(position)
}
3 run
使用场景:run属于let和with的结合体,既可以像let一样做非空判断,也可以像with一样避免重复使用类名调用方法,跟with的区别就是把Receiver放在了外边,内部只有一个lambda表达式
var user1:User? = null
user1?.run {
println("用户名$name 年龄$age")
}
var user1:User? = User("kkk",12)
var result = user1?.run {
println("用户名$name 年龄$age")
1000
2000
}
println(result)
输出:
用户名kkk 年龄12
2000
run是通过闭包的形式,返回最后一行代码的值
4 apply
使用场景:apply的使用场景和run类似,但是apply和run不同的是,apply返回的是当前对象,而run返回的是最后一行代码的值;因此apply可以做一些对象的初始化操作,或者为对象动态绑定数据返回;
var new = user1?.apply {
name = "james"
age = 24
}
println(new)
输出:
User(name=james, age=24)
一些动态加载View的场景,也可以通过apply来实现,例如给TabLayout的每个Tab添加文本,就可以通过apply,返回的就是赋值之后的Tab
mediator = TabLayoutMediator(tablayout,vp_news) { tab, position ->
tab.apply {
//做View的初始化
var tabView = TextView(this@NewsActivity)
tabView.text = tabs[position]
customView = tabView
}
}
5 also
使用场景:和let使用的场景一致,但是let返回的是代码的最后一行,而also返回的是对象本身,
val res: String? = "jjk"
val newString = res?.let {
it + "123"
"2000"
}
println("处理后的字符串:" + newString)
let输出:2000
alse输出:jjk123
其中和apply的不同支持在于,also是没法像apply那样拿到对象的属性进行操作,缺少with的方式
6 高阶函数
当一个函数中,存在一个函数作为参数,或者返回值为一个函数,那么这个函数就是一个高阶函数
private fun lambda(a:()->String = {"jss"}) : String{
return a()
}
例如上边这个函数,参数a就是用一个函数作为参数,那么lambda就是一个高阶函数,可以给这个参数赋值初始值
使用方式,可以直接用lambda表达式
val js = lambda {
"123"
}
如果想要使用默认值,那么就直接使用val js = lambda()
如果存在两个函数式参数,且没有赋值,那么就需要显示地声明出来,且只有最后一个参数可以通过lambda表达式的方式声明
private fun lambda(a:()->String = {"jss"},b:(()->Unit)? = null) : String{
println(b)
return a()
}
因为都存在默认值,且第二个参数可为空,那么可以直接使用val js = lambda()
private fun lambda(a:()->String = {"jss"},b:(()->String)? = null) : String{
if (b != null) {
return operationA(b())
}
return a()
}
private fun operationA( arr:String) : String{
return arr
}
高阶函数,可以传入函数参数,做条件判断
这部分是在看ViewModel源码的时候看到的,在这里分享一下,对于高阶函数的使用方式