Swift泛型类型扩展编译失败求助:如何约束B<J>的J为A<I>
Swift泛型扩展问题解答
你的需求是可以实现的,原代码编译失败是因为extension B的约束里,I没有明确的来源——编译器不知道这个I是从哪来的,所以报错。
下面提供几种可行的实现方式:
方式一:直接约束J为A<Hashable类型>(Swift 5.7+)
如果不需要在扩展里直接使用I这个类型,只是想限定J是A且其泛型参数符合Hashable,可以用some关键字简化约束:
struct A<I> {} struct B<J> {} extension A where I: Hashable {} // 编译正常的扩展 extension B where J == A<some Hashable> {}
方式二:通过协议关联类型约束(兼容更早Swift版本)
如果需要在扩展里直接访问I的类型,可以给A定义一个带关联类型的协议,再通过协议约束B的泛型参数:
struct A<I> {} struct B<J> {} // 定义协议,让A遵循它 protocol ACompatible { associatedtype I } extension A: ACompatible {} extension A where I: Hashable {} // 编译正常的扩展,同时能在扩展里通过J.I访问泛型参数I extension B where J: ACompatible, J.I: Hashable { func test() { // 示例:使用J.I类型 let value: J.I? = nil } }
方式三:显式声明泛型依赖
如果需要在扩展里直接使用I作为显式类型,也可以通过明确泛型参数的依赖关系实现:
struct A<I> {} struct B<J> {} extension A where I: Hashable {} // 编译正常的扩展,直接使用I类型 extension B where J == A<I>, I: Hashable { func anotherTest() -> I? { return nil } }
这类泛型扩展完全可行,核心是让编译器能清晰推断出泛型参数之间的依赖关系,避免出现无来源的泛型标识符。
内容的提问来源于stack exchange,提问作者蘇哲聖
相关产品推荐
相关产品推荐

