4 ms·
Do Go generics support covariance and contravariance?
by cryptos 5y ago
Do Go generics support covariance and contravariance?
- Kranar 5y agoGo does not have subtypes, so your question is not applicable.
- lamontcg 5y agoCan you use generics to create a container of an interface or does it only support concrete types as generics?
- deleted 5y ago[deleted]
- deleted 5y ago[deleted]
- whateveracct 5y agoIt does have subtyping relationships via interface. It absolutely has subtypes in the co/contravariance. In theory, a slice of structs that implement an interface should be able to be used as a slice of that interface. But due to the implementation, that requires a full copy.
- ithkuil 5y agoNo it's not due to the implementation, it's due to the language specification: there is no general subtyping. You can see it this way: there is implicit syntactic sugar that creates an interface value (pointer + type info) when you assign a value of type T to a variable of type interface I where T implements I. This happens on variable assignment, function parameter bindings and return value bindings. A slice of Is is just a very different type from a slice of Ts. The assignment magic sugar works, but it works at the level of slice elements, not the whole slice.
- deleted 5y ago[deleted]
- codeflo 5y agoIt’s not just a random implementation artifact. Since all slices in Go are mutable, it logically wouldn’t make sense to upcast them while keeping the reference. That would mean the ability to put other objects in the slice. Same for pointers. That’s a basic fact of type safety that people often get wrong. For example, the JVM famously allows upcasting arrays, with very surprising results.
- whateveracct 5y agoAh yes that's true it is mutable But even an immutable list cannot be made covariant. Or, say, funcs.
- josefx 5y agoJava fixed the mutability issue for its generics, you can insert Cats and Dogs into a concrete List<Animal>, but you cannot insert them into a List<? extends Animal>.
- masklinn 5y ago> a slice of structs that implement an interface should be able to be used as a slice of that interface It absolutely should not even if it could (which it can not since the memory layouts don’t match), as that undermines the type system.
- whateveracct 5y agoIf it were immutable at least, the type system wouldn't be undermined at all.
- masklinn 5y ago> If it were immutable at least Yeah but immutability’s not even remotely a thing in go land.