斯威夫特协变的泛型
问题描述:
这里是希望我实现一个例子:斯威夫特协变的泛型
protocol SomeType {}
class SomeClass: SomeType {}
struct SomeGenericStruct<A> {
typealias E = A
}
func take(someType: SomeGenericStruct<SomeType>) {}
let concreteGenericStruct1: SomeGenericStruct<SomeType> = SomeGenericStruct<SomeType>()
let concreteGenericStruct2: SomeGenericStruct<SomeClass> = SomeGenericStruct<SomeClass>()
take(concreteGenericStruct1)
take(concreteGenericStruct2) // much no work, very repair. wow.
或者更简单:
let concreteGenericStruct3: SomeGenericStruct<SomeType> = SomeGenericStruct<SomeClass>() as SomeGenericStruct<SomeType> // still no work
如何管理提供take
与concreteGenericStruct2
?
答
您可以使用通用的方法是:
func take<T where T: SomeType>(someType: SomeGenericStruct<T>) { }
与此唯一的问题是,你不能通过SomeGenericStruct<SomeType>
它。它必须是一个具体类型的泛型。如果完全有必要,你可以只有两个功能本质上做同样的事情:
func take(someInput: SomeGenericStruct<SomeType>) { /* do stuff */ }
func take<T where T: SomeType>(someType: SomeGenericStruct<T>) { /* do same stuff */ }
你不能。正如你注意到的那样,Swift泛型不是协变的。 (数组是协变的,但编译器为它们提供了一个特例,你不能重新创建它。)Anton的方法可能是针对你的精确问题的最好方法,但更有可能你需要重新考虑如何处理你的数据,特别是避免子类化(这是希望协变的常见原因,尽管你在这里用协议演示它)。 –