[英]Nested Swift 4 Codable Struct uses CodingKeys irregularly
[英]Codable and CodingKeys
我正在尝试实现一个与Codable
如何使用CodingKeys
枚举具有类似功能的协议。
使用Codable
和CodingKeys
,如果您没有在CodingKeys
枚举中为Codable
对象上的每个属性实现 case,则会导致编译器错误,指出该对象不符合协议。
我查看了文档,唯一能找到的与Codable
( Encodable
and Decodable
) 协议相关的是实现func encode(to encoder: Encoder)
和init(from decoder: Decoder)
函数的要求。
我得到的最接近的是定义如下协议:
protocol TestProtocol {
associatedType Keys: CodingKey
}
这要求实现者有一个符合CodingKey
的Keys
属性,但它并不强制要求所有属性都有一个案例。 此外,您不能像使用Codable
一样将Keys
属性声明为私有。
Codable
和CodingKeys
处理的层次是否比通过 API 公开的更深?
如果没有,有没有办法在Codable
之外实现CodingKeys
功能?
你问两个问题。 我认为以相反的顺序解释它们会更容易。
Codable 和 CodingKeys 的处理层次是否比通过 API 公开的更深?
是的,Swift 编译器知道Encodable
、 Decodable
和CodingKey
协议,并为它们提供了特殊的代码。
如果满足某些条件,编译器可以合成一个名为CodingKeys
的CodingKey
的enum
、 init(from:)
初始化程序和encode(to:)
方法。 SE-0166中详细说明了这些条件:
也可以为某些类型自动合成可
Encodable
和可Decodable
要求:
- 符合
Encodable
其属性都是Encodable
的类型会自动生成String
支持的CodingKey
enum
映射属性到案例名称。 类似地,对于其属性都是Decodable
的Decodable
类型- 属于 (1) 的类型——以及手动提供
CodingKey
enum
(直接命名为CodingKeys
或通过typealias
命名)的类型,其情况按名称一对一映射到Encodable
/Decodable
属性——自动合成init(from:)
和encode(to:)
酌情使用这些属性和键- 如果需要,既不属于 (1) 也不属于 (2) 的类型必须提供自定义键类型,并酌情提供它们自己的
init(from:)
和encode(to:)
请注意,与CodingKey
兼容的类型通常不必命名为CodingKeys
甚至是enum
,除非您依赖编译器综合的一致性。
此外,请注意,如果您依赖编译器来合成init(from:)
或encode(to:)
,则符合CodingKey
的CodingKeys
类型只需要为其封闭类型的每个成员都有一个案例。
如果您手动实现init(from:)
和encode(to:)
,您可以为CodingKey
的类型使用任何名称,并且它只需要包含您关心的情况。 如果您仅使用单值容器或无键容器进行存储,您甚至不需要CodingKey
的类型。
如果没有,有没有办法在 Codable 之外实现 CodingKeys 功能?
如果“功能”是指编译器自动合成实现的方式,那么唯一的方法是使用代码生成器(如 Sourcery 或 gyb)生成源代码并将其提供给编译器。
如果“功能”是指编译器需要为封闭类型的每个Encodable
/ Decodable
成员提供一个关键成员的方式,那么唯一的方法是运行一个单独的程序来分析您的源代码并在任何情况下排除错误失踪。 你不能让标准的 Swift 编译器为你做这件事。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.