如需转载请评论或简信,并注明出处,未经允许不得转载
Kotlin系列导读
Kotlin学习手册(一)类与继承
Kotlin学习手册(二)属性与字段
Kotlin学习手册(三)接口
Kotlin学习手册(四)内部类
Kotlin学习手册(五)函数
Kotlin学习手册(六)数组与集合
Kotlin学习手册(七)for循环
Kotlin学习手册(八)内联函数let、with、run、apply、also
Kotlin学习手册(九)空类型安全
Kotlin学习手册(十)带你真正理解什么是Kotlin协程
目录
let
函数结构
object.let{
//在函数体内使用it替代object对象去访问其公有的属性和方法
it.todo()
...
}
//另一种用途 判断object为null的操作
//表示object不为null的条件下,才会去执行let函数体
object?.let{
it.todo()
}
适用的场景
使用let函数处理需要针对一个可null的对象统一做判空处理(常用)
需要去明确一个变量所处特定的作用域范围内可以使用
例子
- 不使用
let
mTextView?.textSize(...)
mTextView?.setTextColor(...)
mTextView?.background(..)
- 使用
let
mTextView?.let{
it..textSize(...)
it.setTextColor(...)
it.background(..)
}
特点
- 函数体内使用
it
指代当前对象 - 返回值为函数块的最后一行或指定
return
表达式 - 可以在调用
let
之前判空处理
with
函数结构
with(object){
//todo
}
适用的场景
- 适用于调用同一个类的多个方法时,可以省去类名重复,直接调用类的方法即可(经常用于Android中RecyclerView中onBinderViewHolder中,数据model的属性映射到UI上)
例子
- 不使用
with
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
itemView.shop_tv_edit.setOnClickListener(listener)
itemView.shop_tv_insert.setOnClickListener(listener)
itemView.shop_tv_show.setOnClickListener(listener)
itemView.shop_tv_hide.setOnClickListener(listener)
}
- 使用
with
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
with(itemView) {
shop_tv_edit.setOnClickListener(listener)
shop_tv_insert.setOnClickListener(listener)
shop_tv_show.setOnClickListener(listener)
shop_tv_hide.setOnClickListener(listener)
}
}
特点
- 在函数块内可以通过
this
指代当前对象 - 返回值为函数块的最后一行或指定
return
表达式
run
函数结构
object.run{
//todo
}
适用的场景
- 适用于
let
,with
函数任何场景
例子
- 不使用
run
override fun onBindViewHolder(holder: ViewHolder, position: Int){
val item = getItem(position)?: return
with(item){
holder.tvNewsTitle.text = StringUtils.trimToEmpty(titleEn)
holder.tvNewsSummary.text = StringUtils.trimToEmpty(summary)
holder.tvExtraInf = "难度:$gradeInfo | 单词数:$length | 读后感: $numReviews"
}
}
- 使用
run
override fun onBindViewHolder(holder: ViewHolder, position: Int){
getItem(position)?.run{
holder.tvNewsTitle.text = StringUtils.trimToEmpty(titleEn)
holder.tvNewsSummary.text = StringUtils.trimToEmpty(summary)
holder.tvExtraInf = "难度:$gradeInfo | 单词数:$length | 读后感: $numReviews"
}
}
特点
- 函数体内使用
this
指代当前对象或者省略 - 返回值为函数块的最后一行或指定
return
表达式 - 可以在调用
run
之前判空处理
run
函数是let
,with
两个函数结合体,适用于let
,with
函数任何场景。准确来说它弥补了let
函数在函数体内必须使用it
参数替代对象,在run
函数中可以像with
函数一样可以省略,直接访问实例的公有属性和方法,另一方面它弥补了with
函数传入对象判空问题,在run
函数中可以像let
函数一样做判空处理
apply
函数结构
object.apply{
//todo
}
适用的场景
适用于
run
函数的任何场景,一般用于初始化一个对象实例的时候,操作对象属性,并最终返回这个对象动态
inflate
出一个XML的view
的时候需要给view
绑定数据一般可用于多个扩展函数链式调用
数据
model
多层级包裹判空处理的问题
例子
- 不使用
apply
val wgDialog = WGDialog(this@ShopStuffActivity)
wgDialog.message = "该页面尚未保存,是否返回?"
wgDialog.btnLeft = "取消"
wgDialog.btnRight = "确定"
wgDialog.addListener(WGDialog.Item.RIGHT, object: WGDialogInterface.OnClickListener{
override fun onButtonClick(which: Int, isCheck: Boolean) {
finish()
}
})
wgDialog.show()
- 使用
apply
WGDialog(this@ShopStuffActivity).apply {
message = "该页面尚未保存,是否返回?"
btnLeft = "取消"
btnRight = "确定"
addListener(WGDialog.Item.RIGHT, object: WGDialogInterface.OnClickListener{
override fun onButtonClick(which: Int, isCheck: Boolean) {
finish()
}
})
}.show()
特点
- 函数体内使用
this
指代当前对象或者省略 - 返回的值是对象本身(
this
) - 可以在调用
apply
之前判空处理
also
函数结构
object.also{
//todo
}
适用的场景
- 适用于
let
函数的任何场景,唯一的不同是also
返回的值是对象本身(this
),一般可用于多个扩展函数链式调用
例子
- 不使用
also
mTextView?.textSize(...)
mTextView?.setTextColor(...)
mTextView?.background(..)
- 使用
also
mTextView?.also{
it..textSize(...)
it.setTextColor(...)
it.background(..)
}
特点
- 函数体内使用
it
指代当前对象 - 返回的值是对象本身(
this
) - 可以在调用
also
之前判空处理
比较
函数名 | 函数体内使用的对象 | 返回值 |
---|---|---|
let | it | 函数块的最后一行或指定return表达式 |
with | this或省略 | 函数块的最后一行或指定return表达式 |
run | this或省略 | 函数块的最后一行或指定return表达式 |
apply | this或省略 | this |
also | it | this |