casolorz
casolorz

Reputation: 9544

How can I let the Kotlin compiler know I already checked for null inside a function?

Basically I have a function that does some stuff but specifically it checks if two values I'm passing are null. This function is called from various places to make sure those two values are not null. Kotlin is complaining later that I'm not checking for null. Is there a way I can do this so that Kotlin already knows that I am checking for null without using !!?

Here is a simple example:

private fun stuff() {
    var possibleNull: String? = "test"
    if (testNull(possibleNull)) {
        mustPassNonNull(possibleNull)
    }
}

private fun mustPassNonNull(possibleNull: String) {
    //use value that isn't null
}

private fun testNull(possibleNull: String?): Boolean {
    return possibleNull != null
}

Basically testNull is only true if possibleNull is not null and that check is on an if right before calling mustPassNonNull so can I let Kotlin know I'm already checking that? without using !! of course.

Thanks.

Upvotes: 3

Views: 1162

Answers (2)

r2rek
r2rek

Reputation: 2233

It seems like a simple let situation

private fun stuff() {
    var possibleNull: String? = "test"
    possibleNull?.let { mustPassNonNull(it) }
}

This way mustPassNonNull will know that it isn't null :)

Also, if you need to do more than just check for nullability you could do:

possibleNull
    ?.takeIf { /* it's not null here anymore, add any checks you need */}
    ?.let { /* both non-null and checked for whatever you need */}

Upvotes: 0

Matthew Jarvis
Matthew Jarvis

Reputation: 111

It is possible with the use of contracts. Currently in experimental in Kotlin 1.3.

It is possible to declare contracts for your own functions, but this feature is experimental, as the current syntax is in a state of early prototype and will most probably be changed. Also, please note, that currently the Kotlin compiler does not verify contracts, so it's a programmer's responsibility to write correct and sound contracts. -kotlinlang.org

@ExperimentalContracts
fun stuff() {
   var possibleNull: String? = "test"
   if (testNull(possibleNull)) {
      mustPassNonNull(possibleNull)
   }
}

fun mustPassNonNull(possibleNull: String) {
   //use value that isn't null
}

@ExperimentalContracts
fun testNull(possibleNull: String?): Boolean {
   contract{
      returns(true) implies (possibleNull is String)
   }

   return possibleNull != null
}

Articles I referenced:

Upvotes: 5

Related Questions