Consider the following in Swift:
struct GenericStruct<T> {}
class A {}
class B: A {}
func doSomething() -> GenericStruct<A> {
return GenericStruct<B>()
}
This gives the error:
Cannot convert return expression of type
GenericStruct<B>
to return typeGenericStruct<A>
But B
is a subclass of A
.
GenericStruct<B>
to GenericStruct<A>
?Swift generics are invariant, meaning that two generic types are unrelated even if their generic type parameters have an inheritance relation. Invariant generic types cannot be cast to each other since they have no inheritance relation to each other.
This means that GenericStruct<B>
and GenericStruct<A>
are completely unrelated even if B
is a subclass of A
, hence you cannot cast one to the other.
Here's a counter example as to what could happen if this were allowed:
struct GenericStruct<T> {
let value: T
}
class A {}
class B: A {}
class C: A {}
let wrapperOfB: GenericStruct<B> = GenericStruct(value: B())
let wrapperOfA: GenericStruct<A> = wrapperOfB // Suppose GenericStruct<B> was a subtype of GenericStruct<A>
wrapperOfA.value = C() // C is an A, so this should be legal
useB(wrapperOfB.value) // Now what?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With