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

如何无需手动配置,从Codable结构体生成含CodingKeys与值的字典?

自动关联Codable结构体属性与CodingKeys生成字典

核心思路

结合反射(Mirror)和CaseIterable协议解决问题:

  • 让CodingKeys遵循CaseIterable,实现所有编码键的遍历
  • 通过Mirror获取结构体的存储属性及其对应值
  • 将CodingKeys的case名称与属性名匹配,最终用CodingKeys的rawValue作为字典键,属性值作为值

通用解决方案(扩展Codable)

为所有遵循Codable且CodingKeys实现CaseIterable的类型添加通用方法:

extension Codable where Self.CodingKeys: CaseIterable {
    func allValues() -> [String: Any] {
        let mirror = Mirror(reflecting: self)
        var keyValueDict = [String: Any]()
        
        for codingKey in Self.CodingKeys.allCases {
            // CodingKeys的case名称对应结构体属性名
            let propertyName = String(describing: codingKey)
            // 从反射结果中匹配属性并取值
            if let child = mirror.children.first(where: { $0.label == propertyName }) {
                keyValueDict[codingKey.rawValue] = child.value
            }
        }
        
        return keyValueDict
    }
    
    // 如果需要仅返回[String: String]类型的字典
    func allStringValues() -> [String: String] {
        allValues().compactMapValues { $0 as? String }
    }
}

示例使用

修改你的MyStruct,让CodingKeys遵循CaseIterable即可直接调用方法:

struct MyStruct: Codable {
    let propertyOne: String = "Value One"
    let propertyTwo: String = "Value Two"
    
    // 添加CaseIterable协议
    enum CodingKeys: String, CodingKey, CaseIterable {
        case propertyOne = "Coding Key One"
        case propertyTwo = "Coding Key Two"
    }
}

// 使用示例
let myInstance = MyStruct()
print(myInstance.allStringValues())
// 输出:["Coding Key One": "Value One", "Coding Key Two": "Value Two"]

为什么之前的方法不生效?

  • Mirror只能获取属性的名称标签,无法直接关联到CodingKeys的自定义rawValue
  • CaseIterable能遍历所有CodingKeys,但无法直接获取结构体属性的实际值
  • 两者结合刚好互补,完成属性值与编码键的映射

内容的提问来源于stack exchange,提问作者EddiKh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 22:05:27