Odinakachukwu Omaka-chukwu
09/04/2025, 12:40 PMsealed interface RandomState {
data object Empty: RandomState
enum class Validity(val message: String): RandomState {
Valid("Is valid"),
Invalid("Is not valid"),
}
}
fun foo(state: RandomState) {
when(state) {
RandomState.Empty -> Unit
RandomState.Validity.Valid -> {
showMessage(state.message)
}
RandomState.Validity.Invalid -> {
showMessage(state.message)
}
}
}
Why is it not able to smart cast to RandomState.Validity.Valid
and RandomState.Validity.Invalid
?Harish Kabilan
09/04/2025, 1:13 PMsealed interface RandomState {
data object Empty: RandomState
enum class Validity(val message: String): RandomState {
Valid("Is valid"),
Invalid("Is not valid"),
}
}
fun showMessage(message: String) {
println(message)
}
fun foo(state: RandomState) {
when (state) {
RandomState.Empty -> Unit
is RandomState.Validity -> {
showMessage(state.message)
}
}
}
Check if ``state IS RandomState.Validity``
Inside the block, `` state is smart-cast to RandomState.Validity ``Huib Donkers
09/04/2025, 1:25 PMwhen
here checks equality with .equals
which doesn't necessarily imply that the type is the same. However, in this case I think this implication might be correct: it is not possible to override .equals
of enum or data object, and these are the only options for child classes of RandomState
. But the compiler doesn't see this. I wouldn't expect the compiler to try and follow through with this type of reasoning..
• With the interface being sealed
it seems reasonable to conclude that if it's not Empty
then it must be the only remaining type: Validity
, but this is not something the compiler seems to do. Maybe because it would lead to compile errors when adding a new child class that don't seem directly related (rather than "when is not exhaustive", you'd get "unresolved reference"). But maybe there's an even better reason.Odinakachukwu Omaka-chukwu
09/04/2025, 2:43 PM