Swift:如何为AtomicCollection泛型类添加任意集合类型的扩展约束?
Swift 泛型类 AtomicCollection 针对集合类型的扩展方案
问题描述
我想创建一个带泛型的 AtomicCollection 类,并且为泛型类型是 Dictionary 的场景编写扩展。初始代码如下:
public final class AtomicCollection<WrappedValue> { }
我希望让这个类实现 Dictionary、Array、Set 拥有的所有方法,比如 func removeAll()。尝试写扩展时:
extension AtomicCollection where WrappedValue == Dictionary { }
出现错误:Reference to generic type 'Dictionary' requires arguments in <...>,这说明必须指定 Dictionary 的Key和Value类型、Array 的Element类型等。我想为所有的 Dictionary、Array、Set 创建泛型约束,请问有什么解决办法?
解决方案
核心思路
Swift 中 Dictionary、Array、Set 都是带关联类型的泛型类型,直接用具体类型做约束无法覆盖所有变体。我们可以基于 Swift 标准库提供的集合协议做约束,通过协议关联类型匹配所有符合条件的集合实现。
具体实现
首先先完成 AtomicCollection 的基础线程安全封装,再针对不同集合协议编写扩展:
public final class AtomicCollection<WrappedValue> { // 串行队列保证线程安全 private let syncQueue = DispatchQueue(label: "com.atomic.collection.sync") private var wrappedValue: WrappedValue init(initialValue: WrappedValue) { self.wrappedValue = initialValue } // 通用读操作 func read<T>(_ handler: (WrappedValue) -> T) -> T { syncQueue.sync { handler(wrappedValue) } } // 通用写操作 func write(_ handler: (inout WrappedValue) -> Void) { syncQueue.sync { handler(&wrappedValue) } } } // 针对所有遵循RangeReplaceableCollection的集合(Array/Set/Dictionary都符合) extension AtomicCollection where WrappedValue: RangeReplaceableCollection { func removeAll(keepingCapacity keepCapacity: Bool = false) { write { $0.removeAll(keepingCapacity: keepCapacity) } } func append(_ element: WrappedValue.Element) { write { $0.append(element) } } // 可以继续实现RangeReplaceableCollection的其他方法,比如insert、remove(at:)等 } // 针对Dictionary的专属扩展 extension AtomicCollection where WrappedValue: DictionaryProtocol { subscript(key: WrappedValue.Key) -> WrappedValue.Value? { get { read { $0[key] } } set { write { $0[key] = newValue } } } func removeValue(forKey key: WrappedValue.Key) -> WrappedValue.Value? { write { $0.removeValue(forKey: key) } } // 实现Dictionary特有的方法,比如merge、updateValue等 } // 针对Set的专属扩展 extension AtomicCollection where WrappedValue: SetAlgebra { func insert(_ newMember: WrappedValue.Element) -> (inserted: Bool, memberAfterInsert: WrappedValue.Element) { write { $0.insert(newMember) } } func remove(_ member: WrappedValue.Element) -> WrappedValue.Element? { write { $0.remove(member) } } // 实现Set特有的方法,比如union、intersection等 }
说明
- 借助标准库协议(
RangeReplaceableCollection、DictionaryProtocol、SetAlgebra),无需指定具体泛型参数即可覆盖所有对应集合的变体 - 基础类中的
read/write方法封装了线程安全逻辑,所有扩展方法都基于这两个方法实现,保证原子性 - 可以根据需求扩展任意集合协议的方法,完全覆盖
Array、Set、Dictionary的原生API
内容的提问来源于stack exchange,提问作者YanivH
相关产品推荐
相关产品推荐

