(Edited for clarity)
I keep finding myself writing (if (x) f() else null) ?: (if (y) g() else null) ?: (if (z) h() else null)
and similar and I'm sure I'm not the only oneץ
I'm always reaching for a function like valueIf
defined below (which is takeIf
with order of parameters reversed so the value is lazy) , which would let me write code like getViewEventType2()
instead of code like getViewEventType1()
(both elaborated below).
Is there an idiom I'm missing?
(Also, is the compiler smart about functions like this, or should I fear creating too many temporary closures?)
private fun getViewEventType1(): String? {
return if (intent.action == "android.intent.action.VIEW") {
intent.data?.pathSegments?.let {
if (it.size == 3 && it[0] == "app" && it[1] == "event") it[2]
else null
}
} else null
}
private fun getViewEventType2(): String? {
return valueIf(intent.action == "android.intent.action.VIEW") {
intent.data?.pathSegments?.let {
valueIf(it.size == 3 && it[0] == "app" && it[1] == "event") { it[2] }
}
}
}
inline fun <T> valueIf(condition: Boolean, func: () -> T?) =
if (condition) func() else null
You can still use takeIf()
to achieve what you want, like shown here in an extension function on Intent
:
fun Intent.getViewEventType(): String? {
return takeIf { it.action == "android.intent.action.VIEW" }
?.`data`
?.pathSegments
?.takeIf { it.size == 3 && it[0] == "app" && it[1] == "event" }
?.get(2)
}
Edit by OP: this is the final code I went with:
fun getViewEventType(): String? {
return intent.takeIf { it.action == "android.intent.action.VIEW" }
?.`data`
?.pathSegments
?.takeIf { it.size == 3 && it[0] == "app" && it[1] == "event" }
?.get(2)
}