使用Kotlin takeIf(或takeUnless)

原文链接

在Kotlin的标准函数,有两大函数,即takeIftakeUnless,乍一看,有什么特别之处呢?这几乎就是if

或者极端点,把每一个if语句改成类似下面(推荐)。

//原始代码
if(status){doThis()}
//修改后的代码
takeIf {status}?apply {doThis()}
复制代码

深入探讨

像其他任何东西一样,takeIf(或takeUnless)确实有它的使用场景。我通过不同情况分享我对他们的理解。在此之前,让我们看看它的实现。

函数签名
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? 
    = if (predicate(this)) this else null
复制代码

从函数签名,我们注意到

  1. 它是从T对象本身调用的。即T.takeIf
  2. predicate函数以T对象为参数
  3. 等待predicate评估后它返回thisnull

合理的使用情况

基于以上特点,我可以推导出它相对于if的使用情况,如下:

1.它是从T对象本身调用的。即T.takeIf

它可以很好处理可空性检查。一个例子如下

//原始代码
if(someObject!= null && status){ 
   doThis()
}
//改进的代码
someObject?.takeIf {status}?apply {doThis()}
复制代码
2.predicate函数以T对象为参数

由于将T作为predicate的参数,所以可以进一步简化takeIf代码

//原始代码
if(someObject!= null && someObject.status){ 
   doThis()
} 
//更好的代码
if(someObject?.status == true){ 
   doThis()
}
//改进的代码
someObject?.takeIf {it.status} ?. apply {doThis()}
复制代码

更好的代码的确还可以,但需要显式的true关键词,所以并不理想。

3.等待predicate评估后它返回thisnull

既然它返回this,那就可以用来进行链式调用。因此,下面代码可以优化

//原始代码
if(someObject!= null && someObject.status){ 
   someObject.doThis()
}
//改进的代码
someObject?.takeIf {status}?doThis()
复制代码

或者实现获取数据或退出的更好方式(例子从Kotlin Doc中摘取)

val index 
   = input.indexOf(keyword).takeIf {it> = 0}?:error(“Error”)
val outFile 
   = File(outputDir.path).takeIf {it.exists()}?:return  false
复制代码

注意

看看下面的代码。

//语法上仍然正确。但逻辑错误!
someObject?.takeIf {status} .apply {doThis()}

//正确的(注意可空性检查?)
someObject?.takeIf {status} ?.apply {doThis()}
复制代码

doThis()在第一行中不管statustrue 还是 false 都会执行。因为 即使takeIf返回null,它仍然会被调用。(这里假设doThis()不是someObject的函数)

所以在这里,第二行的? 是非常微妙且重要的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值