kotlin lambda 简化
————————kotlin 回调函数、let、also、run 、with、apply 使用总结
Lambda 表达式(lambda expression
)是一个匿名函数。编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。
- 回调函数
- 内联函数 let
- 内联函数 also
- 内联函数 with
- 内联函数 run
- 内联函数 apply
- 用法总结
一、回调函数
- 回调函数的Java写法
mEditText.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable editable) {
// TODO
}
});
- 回调函数的kotlin写法
mEditText?.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(editable: Editable) {
// TODO
}
})
- 在Kotlin中,对于
接口只有一个回调的方法,符合使用lambda
mEditText.addTextChangedListener({
editable: Editable ->
// TODO
})
// 如果以上代码中没有回调参数的话,可以直接把editable去掉
mEditText.addTextChangedListener({
// TODO
})
// addTextChangedListener 函数最后一个参数是一个函数,可以直接把括号的实现提到圆括号外面
mEditText.addTextChangedListener(){
// TODO
}
// addTextChangedListener函数只有一个参数,可以直接省略圆括号
mEditText.addTextChangedListener{
// TODO
}
二、内联函数 let
表示object不为null的条件下,才会去执行let函数体
// 表示object不为null的条件下,才会去执行let函数体
mEditText = findViewById<EditText>(R.id.search_et);
mEditText?.let {
// it.todo()
it.setSelection(0)
}
三、内联函数 also
从结构上看also
和let
比较像。不同点是它们各自返回的值不一样,let函数
是以闭包形式返回最后一行代码的值,如果最后一行为空就返回一个Unit类型的默认值;also函数
的返回的是传入对象本身。
// 表示object不为null的条件下,才会去执行let函数体
mEditText = findViewById<EditText>(R.id.search_et).also {
// it.todo()
it.setSelection(0)
}
四、内联函数 with
适用于调用同一个类的多个方法时,可以省去类名重复
,直接调用类的方法即可
- with 一般结构
with(object){
//todo
}
- with 简化过程
// with函数最原始样子如下:
val result = with(user, {
println("my name is $name, I am $age years old, my phone number is $phoneNum")
1000
})
// 由于with函数最后一个参数是一个函数,可以把函数提到圆括号的外部,所以最终with函数的调用形式如下:
val result = with(user) {
println("my name is $name, I am $age years old, my phone number is $phoneNum")
1000
}
- with 使用场景
适用于调用同一个类的多个方法时,可以省去类名重复
,直接调用类的方法即可
// java 写法
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
ItemBean item = getItem(position);
if (item == null) {
return;
}
holder.mTitleTv.setText(item.title);
holder.mSubTitleTv.setText(item.subTitle);
holder.mDescTv.setText(item.desc);
}
// kotlin 写法
override fun onBindViewHolder(holder: ViewHolder, position: Int){
val item = getItem(position)?: return
//
with(item){
holder.mTitleTv.text = title
holder.mSubTitleTv.text = subTitle
holder.mDescTv.text = desc
}
}
五、内联函数 run
- run 适用场景
适用于let、with函数任何场景。
run函数是let、with两个函数结合体,它弥补了let函数在函数体内必须使用it参数替代对象,在run函数中可以像with函数一样,直接访问实例的公有属性和方法;
另一方面它弥补了with函数传入对象判空问题,在run函数中可以像let函数一样做判空处理;
// 借助上边案例的代码:内联函数 with
override fun onBindViewHolder(holder: ViewHolder, position: Int){
val item = getItem(position)?: return
//
with(item){
holder.mTitleTv.text = title
holder.mSubTitleTv.text = subTitle
holder.mDescTv.text = desc
}
}
// 内联函数 run
override fun onBindViewHolder(holder: ViewHolder, position: Int){
val item = getItem(position)?: return
item?.run{
holder.mTitleTv.text = title
holder.mSubTitleTv.text = subTitle
holder.mDescTv.text = desc
}
}
六、内联函数 apply
从结构上看apply
和run
比较像。不同点是它们各自返回的值不一样,run函数
是以闭包形式返回最后一行代码的值;apply函数
的返回的是传入对象本身。
因此apply函数
一般用于一个对象实例初始化的时候,需要对对象中的属性进行赋值;或者动态inflate出一个XML的View的时候需要给View绑定数据也会用到;
// 一个对象实例初始化的时候,需要对对象中的属性进行赋值
mEditText = findViewById<EditText>(R.id.search_et).apply {
// 点击事件
setOnClickListener{
// TODO
}
}
用法总结
- let、also 用于替代判空
- run 、with 用于绑定数据
- apply 用于对象初始化
网友评论