9

I use Kotlin to Programm Android Apps. For null-pointer safety one needs to check if all references are non-null. However if only one is null then we should inform the user that something went wrong.

It is important for me to program in a concise readable manner.

I am looking for a short and easy understandable solution.

The standard way would be:

if  (b != null && a != null && c !=null ...) println ("everything ok.")
else println("Something went wrong")
Marcel Sonderegger
  • 772
  • 1
  • 8
  • 21
  • 2
    Possible duplicate of [Kotlin call function only if all arguments are not null](https://stackoverflow.com/questions/50742094/kotlin-call-function-only-if-all-arguments-are-not-null) – EpicPandaForce Oct 07 '18 at 14:20
  • Although this is a great question, unfortunately it's not a very good fit for StackOverflow, since it's primarily opinion-based. I would suggest you open a discussion at kotlinlang.slack.com, I'm sure you'll get good answers there. – Egor Oct 07 '18 at 14:21
  • 1
    Thank you, I will open a discussion at kotlinlang.slack.com – Marcel Sonderegger Oct 07 '18 at 14:26

2 Answers2

15

Here are two concise ways to write the condition:

listOf(a, b, c).any { it == null }

listOf(a, b, c).filterNotNull().any()

In context, this is how you can use it:

println(if (listOf(a, b).any { it == null })) "Something went wrong"
        else "Everything ok.")
Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • 3
    While this approach is the most concise solution I've seen and should be fine in most cases, the issue I'm having with it is that it doesn't smart cast to non-null when the check only allows code to execute if there are no nulls. – Pilot_51 Jun 18 '20 at 15:33
1

You can use the Elvis operator ?:, which allows to provide a default value in case a value is null (including returning from a function).

For example:

fun foo(a: Int?, b: String?, c: Boolean?) : String? {
    a ?: return null
    b ?: return null
    c ?: return null
    return "Everything ok."
}

The advantage with this approach is that you can have different error results depending on which value is null:

  • Using exceptions:

    fun foo(a: Int?, b: String?, c: Boolean?) : String {
        a ?: throw IllegalArgumentException("a is null")
        b ?: throw IllegalArgumentException("b is null")
        c ?: throw IllegalArgumentException("c is null")
        return "Everything ok."
    }
    
  • Using different return values:

    fun foo(a: Int?, b: String?, c: Boolean?) : Result {
        a ?: return Result.ErrANull
        b ?: return Result.ErrBNull
        c ?: return Result.ErrCNull
        return Result.OK("Everything ok.")
    }
    
    sealed class Result {
        class OK(val s: String) : Result()
        object ErrANull : Result()
        object ErrBNull : Result()
        object ErrCNull : Result()
    }
    
user905686
  • 4,491
  • 8
  • 39
  • 60