原文連接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
的函數)
因此在這裏,第二行的?
是很是微妙且重要的。