最近的项目中也是基本处于是逐渐切换 Kotlin 的状态, 以下是在项目中经常使用到的几个扩展函数, 做一个记录, 不得不说有的时候真的比 Java 方便很多

内联扩展函数之 let

一般可以用来判断 null 的操作,或者是作用域内都使用了这个实例对象 返回值是函数的最后一行, 或者是 return 返回的值, 在作用域里面可使用 it 来代表当前的实例对象

在 Java 中判断空的处理是这样的

1
2
3
if (userInfoBean != null) {
     System.out.println(userInfoBean.name);
}

而在 Kotlin 中的处理是这样的, [ ?. ] 的使用也就是在非空的时候才会执行括号中的代码

1
2
3
4
  // block 是 Unit 类型的, 是函数的最后一行, 或者是 return 的返回值
  val block =  uerInfoBean?.let {
       print(it.name)
  }

内联函数之 with

在函数块内可以通过 this 指代该对象, 返回值是函数的最后一行, 或者是 return 返回的值

举例在适配器中使用, 在 Java 中是这么使用的

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@Override
public void onBindViewHolder(ViewHolder holder, int position) {

    UserInfoBean item = getItem(position);
    if (item == null) {
        return;
    }

    holder.tvName.setText(item.getName());
    holder.tvAge.setText(item.getAge());
}

在 Kotlin 是这么使用的

1
2
3
4
5
6
7
8
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int){
    val item = getItem(position)?: return

    with(item){
        holder.tvName.text = name
        holder.tvAge.text = age
    }
}

内联扩展函数之 run

是 let 和 with 结合体, 返回值是函数的最后一行, 或者是 return 返回的值

借助上一个 Kotlin 的示例, 这里判断 null 直接 return 了, 那么使用 Kotlin 可以简化成这样

1
2
3
4
5
6
7
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int){
		// 在 getItem() 不为 null 的时候才会执行如下代码
    getItem(position)?.run{
        holder.tvName.text = name
        holder.tvAge.text = age
    }
}

内联扩展函数之apply

一般用来初始化的操作, 内部有 this 指代该对象, 返回值是当前调用的对象

1
2
3
4
rv_iot_mode?.apply {
            layoutManager = LinearLayoutManager(this@IoTMainActivity,    LinearLayoutManager.HORIZONTAL, false)
            adapter = mIOTMainSceneModeAdapter
}

或者是这样的, 比如当我们使用 Token 拿到了用户信息, 当用户信息不为 null 的时候, 再使用用户信息的 id 去请求另外一个接口

1
2
3
4
5
6
uerInfoBean?.apply {
        initUserInfoView()
}?.id?.apply {
				// 当用户信息不为 null 的时候, id 也不 null 的时候, 再使用 id 去请求另外一个接口请求
        fetchHomeInfoById(id)
}

内联扩展函数之 also

传入的是当前对象, 内部使用 it 可以引用当前的实例对象, 返回值传入的对象, 和 let 扩展函数有点像, 也就是返回值不同

在 let 能用到的地方, 也可以使用 also

1
2
3
4
  // 返回的是当前传入的对象
  val block =  uerInfoBean?.also {
       print(it.name)
  }

上面 apply 的方式, 用 also 的方式也是可以的

1
2
3
4
5
6
7
uerInfoBean?.also {
        initUserInfoView()
}?.id?.apply {
				// 当前 it 即使代表 id
				// 当用户信息不为 null 的时候, id 也不 null 的时候, 再使用 id 去请求另外一个接口请求
        fetchHomeInfoById(it)
}

上面的几个扩展函数大家在开发中可以使用起来细细体会, 其实很多扩展函数, 可以替代或者是配合使用, 一定程度上相比于 Java 确实会方便许多