Swift条件协议扩展与依赖处理问题求助
解决方案:让Persistor根据Entity是否Equatable自动返回对应count
问题根源
你当前的代码里,DefaultPersistor和MockPersistor都直接实现了协议要求的count属性。在Swift中,具体类型对协议成员的实现优先级高于协议扩展的默认实现——所以即使你给Persistor加了where Entity: Equatable的扩展,也不会被触发,编译器会优先使用类本身的count值。
可行方案
方案一:给具体类添加条件扩展(快速生效)
直接启用你注释掉的两段代码即可:
extension DefaultPersistor where Entity: Equatable { var count: Int { 3 } } extension MockPersistor where Entity: Equatable { var count: Int { 3 } }
针对Equatable Entity的类扩展比类本身的通用实现更具体,编译器会优先选择扩展中的count值。运行后,所有Equatable实体对应的count都会输出3,非Equatable实体保持原有值。
方案二:重构协议设计(更易维护)
如果不想给每个Persistor子类重复写扩展,可以拆分协议的职责,让协议扩展统一处理Equatable判断逻辑:
// Entity struct NonEquatableEntity {} struct EquatableEntity: Equatable {} // Persistor protocol Persistor { associatedtype Entity // 让具体类仅实现基础计数 var baseCount: Int { get } } // 默认实现:非Equatable实体使用基础计数 extension Persistor { var count: Int { baseCount } } // 条件扩展:Equatable实体固定返回3 extension Persistor where Entity: Equatable { var count: Int { 3 } } class DefaultPersistor<Entity>: Persistor { var baseCount: Int { 1 } } class MockPersistor<Entity>: Persistor { var baseCount: Int { 2 } } // Store 无需修改 class Store<P: Persistor> { let persistor: P init(persistor: P) { self.persistor = persistor } var count: Int { persistor.count } } // 测试验证 let storeWithDefaultNonEq = Store(persistor: DefaultPersistor<NonEquatableEntity>()) let storeWithDefaultEq = Store(persistor: DefaultPersistor<EquatableEntity>()) let storeWithMockNonEq = Store(persistor: MockPersistor<NonEquatableEntity>()) let storeWithMockEq = Store(persistor: MockPersistor<EquatableEntity>()) print(storeWithDefaultNonEq.count) // 输出 "1" print(storeWithDefaultEq.count) // 输出 "3" print(storeWithMockNonEq.count) // 输出 "2" print(storeWithMockEq.count) // 输出 "3"
这种设计把逻辑集中在协议层面,后续新增Persistor子类时,只需要实现baseCount即可自动适配Equatable判断,无需额外扩展。
内容的提问来源于stack exchange,提问作者Raskal
相关产品推荐
相关产品推荐

