你问两个问题。我会乱七八糟地回答他们。
Codable 和 CodingKeys 的处理层次是否比通过 API 公开的更深?
是的,Swift 编译器知道Encodable、Decodable和CodingKey协议,并为它们提供了特殊的代码。
如果满足某些条件,编译器可以合成符合标准的 named CodingKey、初始化程序和方法。SE-0166中详细说明了这些条件:enumCodingKeysinit(from:)encode(to:)
Encodable&Decodable需求也可以为某些类型自动合成:
- 符合
Encodable其属性的类型都会Encodable自动生成String- 支持的CodingKey enum映射属性到案例名称。类似地,对于Decodable属性为 all 的类型Decodable
- 属于 (1) 的类型 - 以及手动提供 a
CodingKey enum(命名CodingKeys、直接或通过 a typealias)的类型,其情况按名称一对一映射到Encodable/属性 -使用这些属性和键Decodable获得自动合成init(from:)和酌情encode(to:)
- 如果需要,既不属于 (1) 也不属于 (2) 的类型必须提供自定义键类型,并酌情提供它们自己的
init(from:)和encode(to:)
请注意,除非您依赖编译器综合的一致性,否则通常不必命名CodingKey-compliant 类型甚至不必命名为 an 。CodingKeysenum
此外,请注意,如果您依赖编译器来合成或,则CodingKeys符合 的类型只需要为其封闭类型的每个成员都有一个案例。CodingKeyinit(from:)encode(to:)
如果您手动实现init(from:)and encode(to:),您可以为您CodingKey的兼容类型使用任何名称,并且它只需要包含您关心的案例。CodingKey如果您只使用单值容器或无键容器进行存储,您甚至不需要符合- 标准的类型。
如果没有,有没有办法在 Codable 之外实现 CodingKeys 功能?
如果“功能”是指编译器自动合成实现的方式,那么唯一的方法是使用代码生成器(如 Sourcery 或 gyb)生成源代码并将其提供给编译器。
如果“功能”是指编译器要求每个Encodable/Decodable封闭类型成员的关键成员的方式,那么唯一的方法是运行一个单独的程序来分析您的源代码并在任何情况下丢失错误。你不能让标准的 Swift 编译器为你做这件事。