Conditional side effects and additional types in Kotlin

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 executed when the repository returns a non-zero value and when someCondition is executed.

Is there any way to Kotlin, and not use the if {} - return constructs?

In Java 8, this can be achieved by:

optional
  .filter(...)
  .ifPresent(...)  
+4
source share
3 answers

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 as follows:

repository.findByUID(request.userId)?.takeIf { someCondition }?.let { service -> }

Kotlin does not contain such a method in 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(...)
    }
}

( ):

listOf(repository.findByUID(userId)).filter { someCondition }.forEach { service.run(...) }
+4

Kotlin Java Optional ( Guava Optional).

Kotlin 1.1 takeIf, " filter " (takeIf(), () - Kotlin 1.1 - Kotlin):

repository.findByUID(request.userId).takeIf { !someCondition }?.let { service.run(...) }

Kotlin 1.0 map, flatMap, filter/takeIf .. , . :.

inline fun <T> filter(value: T?, predicate: (T) -> Boolean): T? {
    return if (value != null && predicate(value)) value else null
}

:

filter(repository.findByUID(request.userId)) { !someCondition }?.let { service.run(...) }
+5

libs :

?.let { if (someCondition) null else it }

:

fun handle(request: Request) {
    repository.findByUID(request.userId)
            ?.let { if (someCondition) null else it }
            ?.let {
                service.run {
                    /* ... */
                }
            }
}

Or at least it looks good, and has compiled the same types in my code base after the determination Request, repository, findByUidetc .: -)

0
source

Source: https://habr.com/ru/post/1665086/


All Articles