Oleksii Masnyi
Oleksii Masnyi

Reputation: 2912

Any way to tell Kotlin compiler that prior callable function already did a check for null

If I have a code fragment like

val myNullableString : String?
val resultingString = if (myNullableString.isNullOrBlank()) 
myNullDefaultString else String.format(myNullableString!!, someOtherString)

I have to use myNullableString!! in String.format() since the compiler would not be able to figure out that isNullOrBlank() includes a null-check. Is this correct or is there any way to tell the compiler that a function will infer that the instance is not null?

Upvotes: 2

Views: 144

Answers (3)

Willi Mentzel
Willi Mentzel

Reputation: 29844

Kotlin 1.3 introduced a concept called contracts. From now on you can tell the compiler that a null check has been done. It has already been implemented for all necessary functions in the standard library (for isNullOrBlank() too).

So, your example would compile now without !!

val myNullableString: String? = null

val result = if (myNullableString.isNullOrBlank()) {
    "default"
} else {
    String.format(myNullableString, "hello") // myNullableString is smart-casted to String
}

Upvotes: 1

sandwwraith
sandwwraith

Reputation: 319

Compiler can perform smart cast from nullable type to non-nullable only after explicit check expression, like myNullableString != null

Upvotes: 0

Oleksii Masnyi
Oleksii Masnyi

Reputation: 2912

Didn’t see any mentions that there is a way to tell such info to the compiler, but here is a workaround: having function returning null if string is empty and use let?.{} after that

inline fun String?.nullIfBlank(): String? = if (this?.isBlank() ?: true) null else this

val resultingString: String = myNullableString.nullIfBlank()?.let {
    String.format(it) 
} ?: myNullDefaultString

Upvotes: 0

Related Questions