ant2009
ant2009

Reputation: 22486

Resolving a condition that requires Boolean but found Boolean?

Kotlin 1.4.0

Resolving a condition that requires Boolean but found Boolean?

I have the following code:

detailList.firstOrNull()?.postCode.takeIf { postcode: String? ->
    postcode?.run { this != ZERO }
}?.also { postcode ->
    view.editTextPostcode.setText(postcode)
}

Here I get an error that says required Boolean found Boolean?

As postcode could be null, I am wondering why its not smart casted to a non-null.

This works by removing the safe call operator

detailList.firstOrNull()?.postCode.takeIf { postcode: String? ->
    postcode.run { this != ZERO }
}?.also { postcode ->
    view.editTextPostcode.setText(postcode)
}

In the above, wouldn't this crash if postcode really is null?

This is the code I have used as I check for null and then evaluate the second condition:

detailList.firstOrNull()?.postCode.takeIf { postcode: String? ->
        postcode != null && postcode != ZERO            
}?.also { postcode ->
        view.editTextPostcode.setText(postcode)
}

As @Steyrix noticed in his comment if the postcode is really null then there is no evaluation of the condition.

This is the update that will evaluate the condition and return a true boolean. If postcode is null then it will return false

detailList.firstOrNull()?.postCode.takeIf { postcode: String? ->
    postcode?.run {
        postcode != ZERO
    } ?: false         
}?.also { postcode ->
    view.editTextPostcode.setText(postcode)
}

Upvotes: 0

Views: 1049

Answers (1)

Steyrix
Steyrix

Reputation: 3226

Answering the original question:

postCode is actually not being smart-casted to non-null type, since it is explicitly declared as a variable of nullable type. Evaluation of boolean expression will not happen, when postCode will be null. Since there can be no evaluation, there can be no Boolean but Boolean? instead.

The reason of the return type is not being Unit is that performing of typed method on a nullable instance returns null if the instance is null as well. However, null can represent different types depending on method's return type.

E.g. when having a nullable instance object:

Since the instance is null, calling member methods/fields will return null. object?.intMethod() will return null as Int? and object?.boolMethod() will return null as Boolean?

In your case compiler defines actual return type of takeIf as the nullable return type of run which is Boolean?, since latter method returns result of boolean expression evaluation.

Upvotes: 1

Related Questions