如何为泛型参数约束为Codable的自定义类的数组添加扩展?
问题根源
你遇到的报错本质是你把Codable协议直接当作了具体类型传入Foo的泛型参数,而Swift中协议本身不会遵守自身,自然满足不了Foo要求泛型参数必须遵守Codable的约束,所以编译器抛出错误。
可用解决方案
方案1:泛型约束扩展(推荐,写法最简单)
不需要给Foo指定固定的泛型类型,直接通过约束保证元素是任意符合Codable泛型要求的Foo实例即可:
// Swift 5.7+ 支持some关键字的版本 extension Array where Element: Foo<some Codable> { // 示例方法:把所有元素的bar属性编码为Data func encodeAllBars() throws -> [Data] { try map { try JSONEncoder().encode($0.bar) } } }
如果使用的Swift版本低于5.7,不支持some在扩展约束里的写法,可以调整为方法级别的泛型约束:
extension Array { func encodeAllBars<T: Codable>() throws -> [Data] where Element == Foo<T> { try map { try JSONEncoder().encode($0.bar) } } }
方案2:抽离无泛型协议(适用混合泛型Foo的数组)
如果你的数组里需要存放不同泛型参数的Foo实例(比如同时有Foo<Int>和Foo<String>),可以先抽离不带泛型的公共协议:
// 声明公共协议,把你需要用到的bar的能力暴露出来 protocol FooOperable { var bar: Encodable { get } } // 让所有Foo实例自动遵守该协议 extension Foo: FooOperable {} // 直接约束数组元素遵守该协议即可 extension Array where Element: FooOperable { func encodeAllBars() throws -> [Data] { try map { try JSONEncoder().encode($0.bar) } } }
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

