My understanding is:
The “in” modifier for a generic type, e.g. <in T>
, is used when T can only be the type of an argument to a function.
The “out” modifier, e.g. <out T>
, is used when T can only be the type of a function result, or when T is the type of a constructor argument.
What I don’t get is why “out” applies to constructor argument types. Those aren’t outputs, are they? Was that a convenience to avoid the need for creating a third modifier?
Let’s define
class Wrapper<out T>(val item: T)
The out attribute allows the following:
val wrapper: Wrapper<Any> = Wrapper<String>("hi" )
Now, can you call Wrapper
’s constructor on property wrapper
? No, which is why it’s safe there. Constructor parameters don’t affect the type safety of assignment.
Maybe I’m dense, but I don’t understand how your reply answers my question. I.e., what does “out” have to do with a constructor parameter?
The “out” keyword is just an inexact but mostly intuitive shorthand to declare covariance.
Covariance is the ability for a type C<Derived>
to be used anywhere a C<Base>
is expected.
Using an “out” type parameter as a constructor parameter does not break covariance so it’s allowed.
Thanks. I’ll review covariance and contravariance. It seems like I used to know what those terms meant. But I found some good articles about them.