Swift变异泛型

8
以下是我想要实现的示例:

这里是一个我想要实现的示例:

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


你做不到。正如你所指出的那样,Swift泛型不是协变的。(数组是协变的,但编译器为它们制定了特殊情况;你无法重新创建它们。)Anton的方法可能是针对你精确问题的最佳解决方案,但更有可能的是,你需要重新考虑你如何处理数据,特别是避免子类化(这是想要协变的常见原因,尽管你在这里使用协议来演示)。 - Rob Napier
1个回答

8
您可以使用通用方法来实现这个功能:
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 */ }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接