Hello! I have a number of classes that might or mi...
# codereview
j
Hello! I have a number of classes that might or might not be resolved to some external data source. So that just means wrapping in a container. A combination of optional / decorator pattern.
Copy code
sealed class Resolvable<T>
class Resolved<T>(val value: T, val pk: Long) : Resolvable<T>()
class Unresolved<T>(val value: T) : Resolvable<T>() {
    fun resolved(pk: Long) = Resolved(value, pk)
}
Now I want to take a
Collection<Resolvable<ItemIdentifier>>
and filter only unresolved ones, into a
Collection<Unresolved<ItemIdentifier>>
. This works:
Copy code
val x : Collection<Unresolved<ItemIdentifier>> = itemIdentifiers.mapNotNull { when(it) {is Unresolved -> it else -> null }}
But I wonder if there's a more idiomatic way to do it? (type annotation on
x
just for clarity).
o
Copy code
val x: Collection<Unresolved<ItemIdentifier>> = itemIdentifiers.filterIsInstance<Unresolved<ItemIdentifier>>()
j
!!!! Thank you! Don't know why I didn't see that.
o
Because with an if else, the compiler thinks there is a chance that there would be an else. When basically assures the compiler those are the only 2 cases
j
So the same sealed class guarantees just don't apply to
if
?
d
I think if you put
else error("Invalid case")
after that
if
, it should work.
But it's probably not as nice...
j
Thank you. Not as nice and also not as correct I think. I think there's a clear nudge to use
when
.
t
BTW, there might be an even easier option (as seen here).
Copy code
sealed class Resolvable<T> {
    abstract val value: T
}

data class Resolved<T>(
    override val value: T, 
    val pk: Long
) : Resolvable<T>()

data class Unresolved<T>(
    override val value: T
) : Resolvable<T>()
That way there is always a
value
on a
Resolvable<T>
, no need to unwrap.
j
Thank you! Sorry I didn’t get the notification about this. I did try this approach actually. It works… but in the end it was too verbose to use cleanly.