I am trying to perform a simple side-effect in Kotlin:
fun handle(request: Request) {
repository.findByUID(request.userId)?.let {
if (someCondition) return
service.run(...)
}
}
As you can see, the side-effect should be performed when the repository returns a non-null value and when someCondition is satisfied.
Is there any Kotlin-way of doing this rather than using if{}-return constructs?
In Java 8, it could be achieved by:
optional
.filter(...)
.ifPresent(...)
Update:
Kotlin 1.1 has a method called takeIf
:
/**
* Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null
You can use it this way:
repository.findByUID(request.userId)?.takeIf { someCondition }?.let { service -> }
Kotlin doesn't contain such method in the stdlib.
However, You can define it:
inline fun <K : Any> K.ifPresent(condition: K.() -> Boolean): K? = if (condition()) this else null
Using this method your example can be rewritten as:
fun handle(request: Request) {
repository.findByUID(request.userId)?.ifPresent { someCondition }?.let {
service.run(...)
}
}
Another option may be to use the built in extensions for list (but there is an overhead of using lists):
listOf(repository.findByUID(userId)).filter { someCondition }.forEach { service.run(...) }
Kotlin's nullable types are very similar to Java's Optional (which is very similar to Guava's Optional).
In Kotlin 1.1 you can use takeIf
which "is like filter
for a single value" (takeIf() and also() - What's New in Kotlin 1.1 - Kotlin Programming Language):
repository.findByUID(request.userId).takeIf { !someCondition }?.let { service.run(...) }
Kotlin 1.0 does not define map
, flatMap
, filter
/takeIf
, etc. for nullable types but you can easily define your own function. e.g.:
inline fun <T> filter(value: T?, predicate: (T) -> Boolean): T? {
return if (value != null && predicate(value)) value else null
}
Example usage:
filter(repository.findByUID(request.userId)) { !someCondition }?.let { service.run(...) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With