What is the most readable way to sum two nullable Int in Kotlin?

Viewed 2359

I tried to do something like the following:

val a: Int? = 1
val b: Int? = 1

a?.plus(b)

but it doesn't compile cause plus expects an Int.

I also tried to create a biLet function:

fun <V1, V2, V3> biLet(a: V1?, b: V2?, block: (V1, V2) -> V3): V3? {
    return a?.let {
        b?.let { block(a, b) }
    }
}

and use it like that:

val result = biLet(a, b) { p1, p2 -> p1 + p2 }

but it seems a lot of work for something apparently simple. Is there any simpler solution?

4 Answers

Unfortunately there isn't anything already in the standard library to sum two nullable ints.

What you can do, however, is to create an operator fun for a nullable Int?:

operator fun Int?.plus(other: Int?): Int? = if (this != null && other != null) this + other else null

And then, you can use it normally like the not-null version:

val a: Int? = 2
val b: Int? = 3
val c = a + b

If you don't want to create a function for it, you can always use its body to handle the nullability of the two ints.

Well, for me this one looks the more readable,

val result = if (a != null && b != null) a+b else null

And when one is null other is not-null and you just want the non-null value then maybe like this:

val result = (a?:0)+(b?:0)

The answer really depends what the expected output of adding nulls is.

Should 4 + null = null or 4 + null = 4? and what about null + null?

In my case what I was after is:

  • 4 + 3 = 7
  • 4 + null = 4
  • null + null = null

The below function achieves this behaviour

private fun addNullable(a: Int?, b: Int?): Int? {
    return if (a == null && b == null) {
        null
    } else {
        (a ?: 0) + (b ?: 0)
    }
}

...

val a: Int? = 1
val b: Int? = 1
val result = addNullable(a, b)

Alternatively you can use an operator overload if you want this same behaviour everywhere. The disadvantage of this is when using it it's not clear it's custom behaviour.

operator fun Int?.plus(other: Int?): Int? { 
    return if (this == null && other == null) {
        null
    } else {
        (a ?: 0) + (b ?: 0)
    }
}

...

val a: Int? = 1
val b: Int? = 1
val result = a + b
listOfNotNull(int1, int2, int3).sumOfOrNull { it }

Where the ints are Int?

Related