You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者蘇哲聖

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:42:20