为什么Swift不能自动将泛型类型参数转换为其超类?

fun*_*bro 3 generics swift

在Swift中考虑以下内容:

struct GenericStruct<T> {}
class A {}
class B: A {}

func doSomething() -> GenericStruct<A> {
   return GenericStruct<B>()
}
Run Code Online (Sandbox Code Playgroud)

这给出了错误:

无法将返回表达式转换GenericStruct<B>为返回类型GenericStruct<A>

但是B是它的子类A.

  • 为什么Swift无法转换GenericStruct<B>GenericStruct<A>
  • 在这种情况下应该做些什么?

Dáv*_*tor 9

Swift泛型是不变的,这意味着两个泛型类型是无关的,即使它们的泛型类型参数具有继承关系.不变的泛型类型不能彼此强制转换,因为它们彼此之间没有继承关系.

这意味着,GenericStruct<B>GenericStruct<A>是即使完全无关的B是一个子类A,因此你不能施放一个到另一个.


Ale*_*ica 8

这是一个反例,说明如果允许这样做会发生什么:

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?
Run Code Online (Sandbox Code Playgroud)

  • 我的回答是对他的补充。他是完全正确的,Swift的泛型是不变的。在我的回答中,我详细说明了如果允许OP的提议,那么哪些无效代码将是可能的。 (2认同)