斯威夫特协变的泛型

问题描述:

这里是希望我实现一个例子:斯威夫特协变的泛型

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 

如何管理提供takeconcreteGenericStruct2

+0

你不能。正如你注意到的那样,Swift泛型不是协变的。 (数组是协变的,但编译器为它们提供了一个特例,你不能重新创建它。)Anton的方法可能是针对你的精确问题的最好方法,但更有可能你需要重新考虑如何处理你的数据,特别是避免子类化(这是希望协变的常见原因,尽管你在这里用协议演示它)。 –

您可以使用通用的方法是:

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 */ }