You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:10:28