Codable 和 CodingKeys
Codable and CodingKeys
我正在尝试实现一个与 Codable
如何使用 CodingKeys
枚举具有相似功能的协议。
使用 Codable
和 CodingKeys
,如果您没有在 CodingKeys
枚举中为 Codable
对象上的每个 属性 实现一个 case,它会导致编译器错误,指出该对象不符合协议。
我查看了文档,唯一能找到与 Codable
(Encodable
和 Decodable
)协议相关的是实现 [=20= 的要求] 和 init(from decoder: Decoder)
函数。
我得到的最接近的是如下定义协议:
protocol TestProtocol {
associatedType Keys: CodingKey
}
这要求实现者有一个符合 CodingKey
的 Keys
属性,但它并不强制要求所有属性都有一个案例。此外,您不能像使用 Codable
.
那样将 Keys
属性 声明为私有
Codable
和 CodingKeys
的处理方式是否比通过 API 公开的内容更深?
如果没有,有没有办法在 Codable
之外实现 CodingKeys
功能?
你问了两个问题。我会乱序回答。
Are Codable and CodingKeys are handled at a deeper level than what is exposed through the APIs?
是的,Swift 编译器知道 Encodable
、Decodable
和 CodingKey
协议,并且有针对它们的特殊代码。
如果某些条件是遇见了。 SE-0166:
中详细说明了条件
Encodable
& Decodable
requirements can be automatically synthesized for certain types as well:
- Types conforming to
Encodable
whose properties are all Encodable
get an automatically generated String
-backed CodingKey
enum
mapping properties to case names. Similarly for Decodable
types whose properties are all Decodable
- Types falling into (1) — and types which manually provide a
CodingKey
enum
(named CodingKeys
, directly, or via a typealias
) whose cases map 1-to-1 to Encodable
/Decodable
properties by name — get automatic synthesis of init(from:)
and encode(to:)
as appropriate, using those properties and keys
- Types which fall into neither (1) nor (2) will have to provide a custom key type if needed and provide their own
init(from:)
and encode(to:)
, as appropriate
请注意,符合 CodingKey
的类型通常 没有 被命名为 CodingKeys
甚至是 enum
除非你依赖于编译器综合的一致性。
此外,请注意,如果您依赖编译器来合成 init(from:)
,则符合 CodingKey
的 CodingKeys
类型只需要为其封闭类型的每个成员提供一个 case或 encode(to:)
.
如果您手动实现 init(from:)
和 encode(to:)
,您可以为符合 CodingKey
的类型使用任何名称,并且它只需要包含您关心的案例.如果您仅使用单值容器或无键容器进行存储,您甚至不需要符合 CodingKey
的类型。
If not, is there a way to implement the CodingKeys functionality outside of Codable?
如果您所说的“功能”是指编译器自动合成实现的方式,那么唯一的方法就是使用代码生成器(如 Sourcery 或 gyb)生成源代码并将其提供给编译器。
如果“功能”是指编译器要求封闭类型的每个 Encodable
/Decodable
成员有一个关键成员,那么唯一的方法就是 运行 一个单独的程序,用于分析您的源代码并在任何情况下丢失错误。你不能让标准 Swift 编译器为你做。
我正在尝试实现一个与 Codable
如何使用 CodingKeys
枚举具有相似功能的协议。
使用 Codable
和 CodingKeys
,如果您没有在 CodingKeys
枚举中为 Codable
对象上的每个 属性 实现一个 case,它会导致编译器错误,指出该对象不符合协议。
我查看了文档,唯一能找到与 Codable
(Encodable
和 Decodable
)协议相关的是实现 [=20= 的要求] 和 init(from decoder: Decoder)
函数。
我得到的最接近的是如下定义协议:
protocol TestProtocol {
associatedType Keys: CodingKey
}
这要求实现者有一个符合 CodingKey
的 Keys
属性,但它并不强制要求所有属性都有一个案例。此外,您不能像使用 Codable
.
Keys
属性 声明为私有
Codable
和 CodingKeys
的处理方式是否比通过 API 公开的内容更深?
如果没有,有没有办法在 Codable
之外实现 CodingKeys
功能?
你问了两个问题。我会乱序回答。
Are Codable and CodingKeys are handled at a deeper level than what is exposed through the APIs?
是的,Swift 编译器知道 Encodable
、Decodable
和 CodingKey
协议,并且有针对它们的特殊代码。
如果某些条件是遇见了。 SE-0166:
中详细说明了条件
Encodable
&Decodable
requirements can be automatically synthesized for certain types as well:
- Types conforming to
Encodable
whose properties are allEncodable
get an automatically generatedString
-backedCodingKey
enum
mapping properties to case names. Similarly forDecodable
types whose properties are allDecodable
- 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- 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
请注意,符合 CodingKey
的类型通常 没有 被命名为 CodingKeys
甚至是 enum
除非你依赖于编译器综合的一致性。
此外,请注意,如果您依赖编译器来合成 init(from:)
,则符合 CodingKey
的 CodingKeys
类型只需要为其封闭类型的每个成员提供一个 case或 encode(to:)
.
如果您手动实现 init(from:)
和 encode(to:)
,您可以为符合 CodingKey
的类型使用任何名称,并且它只需要包含您关心的案例.如果您仅使用单值容器或无键容器进行存储,您甚至不需要符合 CodingKey
的类型。
If not, is there a way to implement the CodingKeys functionality outside of Codable?
如果您所说的“功能”是指编译器自动合成实现的方式,那么唯一的方法就是使用代码生成器(如 Sourcery 或 gyb)生成源代码并将其提供给编译器。
如果“功能”是指编译器要求封闭类型的每个 Encodable
/Decodable
成员有一个关键成员,那么唯一的方法就是 运行 一个单独的程序,用于分析您的源代码并在任何情况下丢失错误。你不能让标准 Swift 编译器为你做。