原文连接html
在Kotlin的标准函数,有两大函数,即takeIf
和takeUnless
,乍一看,有什么特别之处呢?这几乎就是if
?git
或者极端点,把每个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
T.takeIf
,predicate
函数以T对象为参数predicate
评估后它返回this
或null
。基于以上特色,我能够推导出它相对于if
的使用状况,以下:less
T.takeIf
,它能够很好处理可空性检查。一个例子以下函数
//原始代码
if(someObject!= null && status){
doThis()
}
//改进的代码
someObject?.takeIf {status}?apply {doThis()}
复制代码
predicate
函数以T对象为参数因为将T做为predicate
的参数,因此能够进一步简化takeIf
代码优化
//原始代码
if(someObject!= null && someObject.status){
doThis()
}
//更好的代码
if(someObject?.status == true){
doThis()
}
//改进的代码
someObject?.takeIf {it.status} ?. apply {doThis()}
复制代码
更好的代码
的确还能够,但须要显式的true
关键词,因此并不理想。this
predicate
评估后它返回this
或null
既然它返回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()
在第一行中无论status
true 仍是 false 都会执行。由于 即便takeIf
返回null
,它仍然会被调用。(这里假设doThis()
不是someObject
的函数)
因此在这里,第二行的?
是很是微妙且重要的。