kotlin

Is there a way to pass smart cast/null check out of the function?


Consider following two examples. The compiler in example1 can tell that the a.number is non-nullable, but if I wrap the check into function this information doesn't get passed out of it.

Is there a way in Kotlin to tell the compiler that factoryAWithNumber result contains a property that is not null? I am thinking something like contracts, but they don't seem to be able to do it.

data class A(
    val name: String,
    val number: Int?,
)

fun factoryAWithNumber(): A? {
    val a = A("2", 2) // A is obtained with unknown property values using another method
    if (a.number == null) {
        return null
    }
    return a
}

fun example1(): Int {
    val a = A("1", 1)
    if (a.number == null) {
        return -1
    }
    return a.number // Compiler knows number cannot be null
}

fun example2(): Int {
    val a = factoryAWithNumber() ?: return -1
    return a.number!! // Compiler does not know
}

Solution

  • Not possible given there is nothing passed in to factoryAWithNumber(). (Currently) Contracts only can look at parameters or returns.

    Think of your request this way: there is a block box that may return a value or null based on some hidden data. At compile time there is no possible way you can know which case it is, so you have to put in place a run-time test.