You need to enable JavaScript to run this app. Swift如何重构带where子句的Savable与Downloadable协议消除冗余?
优惠活动
大模型
产品
解决方案
定价
更多

Swift如何重构带where子句的Savable与Downloadable协议消除冗余?

重复代码的产生根源
  • Swift 协议扩展中实现的方法默认采用静态分派,只有在协议本体中正式声明的方法要求,才会通过协议见证表实现动态分派。
  • 原代码中所有版本的save()都仅实现于协议扩展中,属于静态绑定方法。如果只保留Downloadable的无约束扩展实现,在该上下文环境中编译器能静态匹配到的只有无约束版本的save(),不会根据Self实际的遵循约束自动切换到C1、C1 & C2版本的save(),这就是必须重复编写三份和save()约束完全对应的download()实现的根本原因。
消除重复代码的实现方案

核心逻辑是将save()从静态扩展方法升级为协议本体声明的动态分派要求,打通跨约束的调用链路,让无约束上下文里的save()调用可以自动匹配当前类型的对应实现,完全不需要为Downloadable编写带约束的重复扩展。
实现步骤完全符合现有架构限制:

  • 不改变Savable、Downloadable的协议形式
  • 不引入运行时的遵循状态检查(适配C1、C2带Self/关联类型要求的限制)
  1. 修改Savable协议本体定义,将save()列为协议的正式方法要求
  2. 保留所有原有针对不同约束的save()扩展实现,这些实现会自动编译进对应遵循类型的协议见证表,实现动态分派
  3. 删除Downloadable上所有带where Self:约束的重复download()扩展,仅保留基础无约束版本的实现即可

修改后的完整可运行代码如下:

// 原有约束定义保持不变
protocol C1 { }
protocol C2 { }

// 调整后的Savable协议:正式声明save()为协议要求
protocol Savable {
    func save()
}

// 原有save()的多版本约束实现完全保留
extension Savable {
    func save() {
        print("Perform basic save")
    }
}

extension Savable where Self: C1 {
    func save() {
        print("Perform save C1")
    }
}

extension Savable where Self: C1 & C2 {
    func save() {
        print("Perform save C1 & C2")
    }
}

// 简化后的Downloadable:删除所有重复的带约束扩展
protocol Downloadable: Savable { }
extension Downloadable {
    func download() {
        print("Perform download")
        save()
    }
}

// 原有测试用例保持不变,输出结果与原代码完全一致
class MyClassC1: Downloadable, C1 { }
let obj1 = MyClassC1()
obj1.download()
// 输出结果:
// Perform download
// Perform save C1

class MyClassC1C2: Downloadable, C1, C2 { }
let obj2 = MyClassC1C2()
obj2.download()
// 输出结果:
// Perform download
// Perform save C1 & C2
方案验证
  • 整个匹配流程完全在编译期完成方法表绑定,不需要运行时检测Self对C1、C2的遵循状态,完全适配约束协议不能做运行时检查的限制
  • 架构层面始终保持Savable、Downloadable的纯协议定义,没有引入类、枚举等实体类型,满足原有架构约束
  • 所有原有方法的约束匹配规则、输出行为和原代码完全一致,没有逻辑变更

内容的提问来源于stack exchange,提问作者Lee Kah Seng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.30 16:57:00