Kotlin call function only if all arguments are not null

xinaiz picture xinaiz · Jun 7, 2018 · Viewed 8.7k times · Source

Is there a way in kotlin to prevent function call if all (or some) arguments are null? For example Having function:

fun test(a: Int, b: Int) { /* function body here */ }

I would like to prevent null checks in case when arguments are null. For example, for arguments:

val a: Int? = null
val b: Int? = null 

I would like to replace:

a?.let { b?.let { test(a, b) } }

with:

test(a, b)

I imagine that function definition syntax could look something like this:

fun test(@PreventNullCall a: Int, @PreventNullCall b: Int)

And that would be equivalent to:

fun test(a: Int?, b: Int?) {
    if(a == null) {
        return
    }

    if(b == null) {
        return
    }

    // function body here
}

Is something like that (or similar) possible to reduce caller (and possibly function author) redundant code?

Answer

zsmb13 picture zsmb13 · Jun 7, 2018

If you don't want callers to have to do these checks themselves, you could perform null checks in an intermediary function, and then call into the real implementation when they passed:

fun test(a: Int?, b: Int?) {
    a ?: return
    b ?: return
    realTest(a, b)
}

private fun realTest(a: Int, b: Int) {
    // use params
}

Edit: here's an implementation of the function @Alexey Romanov has proposed below:

inline fun <T1, T2, R> ifAllNonNull(p1: T1?, p2: T2?, function: (T1, T2) -> R): R? {
    p1 ?: return null
    p2 ?: return null
    return function(p1, p2)
}

fun test(a: Int, b: Int) {
    println("$a, $b")
}

val a: Int? = 10
val b: Int? = 5
ifAllNonNull(a, b, ::test)

Of course you'd need to implement the ifAllNonNull function for 2, 3, etc parameters if you have other functions where you need its functionality.