Swift:无需泛型实现含Encodable数组属性的结构体自动合规
问题描述
我想定义一个自动遵循Encodable协议的结构体,其中包含一个存储Encodable元素的数组,但直接编写会报错:
struct EncodableBagB: Encodable { var values: [Encodable] // ❌ Type 'EncodableBagB' does not conform to protocol 'Encodable' }
如果不用数组,将Encodable设为泛型可以解决单个值的存储问题,但这种方式不适用于数组场景:
struct EncodableBagA1<T: Encodable>: Encodable { var value: T // 🤔 可行,但无法用于数组场景 }
把泛型方案套用到数组上时,会失去存储异构元素的能力:
struct EncodableBagB1<T: Encodable>: Encodable { var values: [T] } EncodableBagB1(values: ["A", "B"]) EncodableBagB1(values: ["A", "B", 1]) // ❌ 表达式类型不明确,需要更多上下文
目前唯一的临时解决办法是创建大量重复的泛型结构体,但这种方式非常繁琐,需要为不同元素数量创建对应结构:
struct EncodableBagB1_2<T0: Encodable, T1: Encodable, T2: Encodable, T3: Encodable>: Encodable { var value0: T0 var value1: T1 var value2: T2 var value3: T3 init(_ encodable0: T0, _ encodable1: T1, _ encodable2: T2, _ encodable3: T3) { value0 = encodable0 value1 = encodable1 value2 = encodable2 value3 = encodable3 } // 🤔 可行,但非常冗长,需要为不同元素数量创建大量重复结构(比如仅T0、T0-T1、T0-T1-T2等) }
核心疑问
- Swift 5.7的
some或any关键字能否解决这个问题? - 是否有即将推出的提案会解决该问题?
- 这个问题的专业名称是什么(方便后续查找相关内容)?
我希望尽量避免手动类型擦除(例如AnyEncodable),因为需要对数组中的元素使用Mirror。
注:示例用Encodable简化,实际使用的协议类似:protocol Foo: Encodable { func bar() }。
尝试过的所有方案
// MARK: 单个值场景 struct EncodableBagA: Encodable { var value: Encodable // ❌ Type 'EncodableBagA' does not conform to protocol 'Encodable' } struct EncodableBagA1<T: Encodable>: Encodable { var value: T // 🤔 可行,但无法用于数组场景 } struct EncodableBagA2: Encodable { // ❌ Type 'EncodableBagA2' does not conform to protocol 'Encodable' var value: any Encodable } struct EncodableBagA3: Encodable { var value: some Encodable // ❌ 属性声明了不透明返回类型,但没有可推断底层类型的初始化表达式 } // MARK: 数组场景 struct EncodableBagB: Encodable { // ❌ Type 'EncodableBagB' does not conform to protocol 'Encodable' var values: [any Encodable] } struct EncodableBagB1<T: Encodable>: Encodable { var values: [T] } EncodableBagB1(values: ["A", "B"]) EncodableBagB1(values: ["A", "B", 1]) // ❌ 表达式类型不明确,需要更多上下文 struct EncodableBagB2<T: Encodable>: Encodable { var values: [any T] // ❌ 'any' 对类型参数 'T' 无影响 } struct EncodableBagB3<T: Encodable>: Encodable { // ❌ Type 'EncodableBagB3' does not conform to protocol 'Encodable' var values: [some T] // ❌ '不透明'类型只能指定 'Any'、'AnyObject'、协议和/或基类 } struct EncodableBagB1_1<T0: Encodable, T1: Encodable, T2: Encodable, T3: Encodable>: Encodable { var value0: T0 var value1: T1 var value2: T2 var value3: T3 init(_ encodables: Encodable...) { value0 = encodables[0] // ❌ 无法将类型 'any Encodable' 的值赋给类型 'T0' value1 = encodables[1] // ❌ 无法将类型 'any Encodable' 的值赋给类型 'T1' value2 = encodables[2] // ❌ 无法将类型 'any Encodable' 的值赋给类型 'T2' value3 = encodables[3] // ❌ 无法将类型 'any Encodable' 的值赋给类型 'T3' } } struct EncodableBagB1_2<T0: Encodable, T1: Encodable, T2: Encodable, T3: Encodable>: Encodable { var value0: T0 var value1: T1 var value2: T2 var value3: T3 init(_ encodable0: T0, _ encodable1: T1, _ encodable2: T2, _ encodable3: T3) { value0 = encodable0 value1 = encodable1 value2 = encodable2 value3 = encodable3 } // 🤔 可行,但非常冗长,需要为不同元素数量创建大量重复结构(比如仅T0、T0-T1、T0-T1-T2等) }
内容的提问来源于stack exchange,提问作者Senseful
相关产品推荐
相关产品推荐

