使用Kotlin takeIf(或takeUnless)

原文连接html

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

或者极端点,把每个if语句改为相似下面(推荐)。github

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

深刻探讨

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

函数签名

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

从函数签名,咱们注意到app

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

合理的使用状况

基于以上特色,我能够推导出它相对于if的使用状况,以下:less

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关键词,因此并不理想。this

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

既然它返回this,那就能够用来进行链式调用。所以,下面代码能够优化spa

//原始代码
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的函数)

因此在这里,第二行的? 是很是微妙且重要的。

相关文章
相关标签/搜索