如何将遵循带关联类型协议的对象添加到数组中
解决带关联类型的Observer协议存储数组问题
问题根源
带关联类型的Observer协议属于泛型协议,编译器无法直接确定其具体类型信息,因此不能直接将Observer作为数组元素类型或变量类型使用。
解决方案
方案一:利用Swift 5.7+存在类型约束
通过any关键字声明存在类型,并约束Observer的ValueType与Subject的泛型T一致:
protocol Observer { associatedtype ValueType func update(value: ValueType) } struct Subject<T> { private var observers = [any Observer where Observer.ValueType == T]() mutating func attach<O: Observer>(observer: O) where O.ValueType == T { observers.append(observer) } func notify(value: T) { for observer in observers { observer.update(value: value) } } }
方案二:类型擦除(Type Erasure)
创建类型擦除包装器,将泛型协议转换为具体类型:
protocol Observer { associatedtype ValueType func update(value: ValueType) } // 类型擦除包装器 struct AnyObserver<T>: Observer { private let _update: (T) -> Void init<O: Observer>(_ observer: O) where O.ValueType == T { _update = observer.update } func update(value: T) { _update(value) } } struct Subject<T> { private var observers = [AnyObserver<T>]() mutating func attach<O: Observer>(observer: O) where O.ValueType == T { observers.append(AnyObserver(observer)) } func notify(value: T) { for observer in observers { observer.update(value: value) } } }
方案对比
- 方案一:Swift 5.7+可用,代码更简洁直观,直接利用语言特性解决问题;
- 方案二:兼容低版本Swift,是泛型协议类型擦除的标准实现方式,灵活性强。
内容的提问来源于stack exchange,提问作者Artur Gurgul
相关产品推荐
相关产品推荐

