Is there a way to specify both `in` and `out` boun...
# getting-started
b
Is there a way to specify both
in
and
out
bounds for a generic type? For example, the union of
List<String>
and
List<Object>
can be described by both
in String
and
out Object
, but it doesn't seem like there's any way to express this.
y
List is already
out
by default. Regardless, anything that's
out Object
(or
out Any?
in Kotlin) is just
in whatever
because anything that's returned
out
will be considered the most generic possible type
Any?
b
Using List as an example, probably should have used MutableList to be more accurate. More accurate example:
Copy code
class Parent;
class Child;
class ReadWrite<T: Parent> {
    fun read(): T
    fun write(value: T)
}
I want to allow
value
to be an instance of
Child
- effectively,
T: out Parent & in Child
. This doesn't seem possible, and I can't hack my way around this by defining
fun write(value: Child)
because that causes an ambiguous overload for
T = Child
.
s
It sounds like maybe you just want two different type parameters. As a general pattern:
Copy code
interface Read<out T>
interface Write<in T>
interface ReadWrite<out R, in W: R>: Read<R>, Write<W>
Then, as you say, the union of
ReadWrite<A, A>
and
ReadWrite<B, B>
is
ReadWrite<A, B>
😍. Very occasionally I've found myself wishing
List
followed this pattern as well.
But the downside of having to write
MutableList<T, T>
everywhere instead of
MutableList<T>
might be too high a price to pay 😄
b
Good call. Certainly not ideal but gets the job done and I couldn't come up with a workaround so this is great. A typealias would help with the few places the definition is used, but apparently you can't have nested typealiases which is unfortunate. Either way, I don't need that often and the messy generics in the class is far better than having to cast things around at the use site. Appreciate it! https://github.com/Rhovas/Interpreter/commit/eb60d1711d596a065e3386f2d20b2f87372cc548#diff-15687bb6ec713efe65b2fd04[…]b9db29c56f323a5f3b119ee3535eL3