[英]Codable and CodingKeys
I'm trying to implement a protocol with similar functionality to how Codable
uses the CodingKeys
enum.我正在尝试实现一个与
Codable
如何使用CodingKeys
枚举具有类似功能的协议。
With Codable
and CodingKeys
, if you don't implement a case in the CodingKeys
enum for every property on the Codable
object, it causes a compiler error stating that the object does not conform to the protocol.使用
Codable
和CodingKeys
,如果您没有在CodingKeys
枚举中为Codable
对象上的每个属性实现 case,则会导致编译器错误,指出该对象不符合协议。
I have looked through documentation, and the only thing I can find related to the Codable
( Encodable
and Decodable
) protocol is the requirement to implement the func encode(to encoder: Encoder)
and init(from decoder: Decoder)
functions.我查看了文档,唯一能找到的与
Codable
( Encodable
and Decodable
) 协议相关的是实现func encode(to encoder: Encoder)
和init(from decoder: Decoder)
函数的要求。
The closest I've gotten is defining a protocol as follows:我得到的最接近的是定义如下协议:
protocol TestProtocol {
associatedType Keys: CodingKey
}
This requires the implementer to have a Keys
property that conforms to CodingKey
, but it does not enforce the requirement to have a case for all properties.这要求实现者有一个符合
CodingKey
的Keys
属性,但它并不强制要求所有属性都有一个案例。 Additionally, you cannot declare the Keys
property as private like you can with Codable
.此外,您不能像使用
Codable
一样将Keys
属性声明为私有。
Are Codable
and CodingKeys
handled at a deeper level than what is exposed through the APIs? Codable
和CodingKeys
处理的层次是否比通过 API 公开的更深?
If not, is there a way to implement the CodingKeys
functionality outside of Codable
?如果没有,有没有办法在
Codable
之外实现CodingKeys
功能?
You ask two questions.你问两个问题。 I think it will be easier to explain them in reverse order.
我认为以相反的顺序解释它们会更容易。
Are Codable and CodingKeys are handled at a deeper level than what is exposed through the APIs?
Codable 和 CodingKeys 的处理层次是否比通过 API 公开的更深?
Yes, the Swift compiler knows about the Encodable
, Decodable
, and CodingKey
protocols and has special code for them.是的,Swift 编译器知道
Encodable
、 Decodable
和CodingKey
协议,并为它们提供了特殊的代码。
The compiler can synthesize a CodingKey
-compliant enum
named CodingKeys
, the init(from:)
initializer, and the encode(to:)
method, if some conditions are met.如果满足某些条件,编译器可以合成一个名为
CodingKeys
的CodingKey
的enum
、 init(from:)
初始化程序和encode(to:)
方法。 The conditions are spelled out in SE-0166 : SE-0166中详细说明了这些条件:
Encodable
&Decodable
requirements can be automatically synthesized for certain types as well:也可以为某些类型自动合成可
Encodable
和可Decodable
要求:
- Types conforming to
Encodable
whose properties are allEncodable
get an automatically generatedString
-backedCodingKey
enum
mapping properties to case names.符合
Encodable
其属性都是Encodable
的类型会自动生成String
支持的CodingKey
enum
映射属性到案例名称。 Similarly forDecodable
types whose properties are allDecodable
类似地,对于其属性都是
Decodable
的Decodable
类型- Types falling into (1) — and types which manually provide a
CodingKey
enum
(namedCodingKeys
, directly, or via atypealias
) whose cases map 1-to-1 toEncodable
/Decodable
properties by name — get automatic synthesis ofinit(from:)
andencode(to:)
as appropriate, using those properties and keys属于 (1) 的类型——以及手动提供
CodingKey
enum
(直接命名为CodingKeys
或通过typealias
命名)的类型,其情况按名称一对一映射到Encodable
/Decodable
属性——自动合成init(from:)
和encode(to:)
酌情使用这些属性和键- Types which fall into neither (1) nor (2) will have to provide a custom key type if needed and provide their own
init(from:)
andencode(to:)
, as appropriate如果需要,既不属于 (1) 也不属于 (2) 的类型必须提供自定义键类型,并酌情提供它们自己的
init(from:)
和encode(to:)
Note that the CodingKey
-compliant type does not in general have to be named CodingKeys
or even be an enum
unless you are relying on compiler-synthesized conformance.请注意,与
CodingKey
兼容的类型通常不必命名为CodingKeys
甚至是enum
,除非您依赖编译器综合的一致性。
Furthermore, note that a CodingKeys
type conforming to CodingKey
only needs to have a case for every member of its enclosing type if you are relying on the compiler to synthesize init(from:)
or encode(to:)
.此外,请注意,如果您依赖编译器来合成
init(from:)
或encode(to:)
,则符合CodingKey
的CodingKeys
类型只需要为其封闭类型的每个成员都有一个案例。
If you're manually implementing init(from:)
and encode(to:)
, you can use any name for your CodingKey
-compliant type, and it only has to have the cases you care about.如果您手动实现
init(from:)
和encode(to:)
,您可以为CodingKey
的类型使用任何名称,并且它只需要包含您关心的情况。 You don't even need a CodingKey
-compliant type if you're only using a single-value container or an unkeyed container for storage.如果您仅使用单值容器或无键容器进行存储,您甚至不需要
CodingKey
的类型。
If not, is there a way to implement the CodingKeys functionality outside of Codable?
如果没有,有没有办法在 Codable 之外实现 CodingKeys 功能?
If, by “functionality”, you mean the way the compiler automatically synthesizes implementations, then the only way is by using a code generator (like Sourcery or gyb) to generate source code and feed it to the compiler.如果“功能”是指编译器自动合成实现的方式,那么唯一的方法是使用代码生成器(如 Sourcery 或 gyb)生成源代码并将其提供给编译器。
If, by “functionality”, you mean the way the compiler requires a key member for each Encodable
/ Decodable
member of the enclosing type, then the only way is by running a separate program that analyzes your source code and errors out if any case is missing.如果“功能”是指编译器需要为封闭类型的每个
Encodable
/ Decodable
成员提供一个关键成员的方式,那么唯一的方法是运行一个单独的程序来分析您的源代码并在任何情况下排除错误失踪。 You can't make the standard Swift compiler do it for you.你不能让标准的 Swift 编译器为你做这件事。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.