Is it expected behavior? I thought that `Surface` ...
# getting-started
m
Is it expected behavior? I thought that
Surface
is subset of
Surface?
so it will be expanded to it. If unusual or should not happen I will try to make a minimal reproducible example out of https://github.com/streetcomplete/StreetComplete/pull/4642#pullrequestreview-1304594775
For now I created
Copy code
fun Surface.asItem(): DisplayItem<Surface> = Item(this, iconResId, titleResId)
and
Copy code
fun Surface.asItemWithFakeNullPossibility(): DisplayItem<Surface?> = Item(this, iconResId, titleResId)
but I suspect there is a better way to handle this...
w
If you did not specify that the generic parameter of
DisplayItem
is
out
, then this is expected. I think you want to add
out
👀 1
m
I have not specified it, I guess I need to learn what
out
is doing
m
Surface
is a subtype of
Surface?
but that doesn't make
DisplayItem<Surface>
a subtype of
DisplayItem<Surface?>
. The subtyping of the generic types are based on the variance. A good explanation. https://typealias.com/guides/illustrated-guide-covariance-contravariance/
👀 1
🔥 1
m
Thanks for hints!
but that doesn't make
DisplayItem<Surface>
a subtype of
DisplayItem<Surface?>
I see that I need to learn more, I was expecting exact opposite (and got confused what is going on)
If you have a better place to learn about
out
than official docs - please let me know!
m
I think typealias is the best place.
e
Producer<T>
is a subtype of
Producer<T?>
Consumer<T?>
is a subtype of
Consumer<T>
m
But the
out
and
in
keywords change the variance of the generics which changes the subtyping rules.
e
Kotlin uses the terms
in
and
out
because that's where it goes
e.g. a consumer can take
in T
, a producer gives
out T
🔥 3
c
New users (of any language) are often confused by variance because we tend to think of immutable data structures, which are always covariant (a
List<Int>
is a
List<Number>
), but this is unsafe if the list can be modified
e
for historical (Java) reasons, arrays are covariant, even though it's unsafe