Swift 可编码和编码键

Swift 可编码和编码键,swift,codable,decodable,encodable,Swift,Codable,Decodable,Encodable,我正在尝试实现一个协议,其功能与Codable使用CodingKeys枚举的方式类似 对于Codable和CodingKeys,如果未在CodingKeys枚举中为可编码对象上的每个属性实现大小写,则会导致编译器错误,指出该对象不符合协议 我已经阅读了文档,我能找到的唯一与可编码和可解码协议相关的东西是实现func encodeto encoder:encoder和initfrom decoder:decoder函数的要求 我得到的最接近的结果是定义一个协议,如下所示: protocol Tes

我正在尝试实现一个协议,其功能与Codable使用CodingKeys枚举的方式类似

对于Codable和CodingKeys,如果未在CodingKeys枚举中为可编码对象上的每个属性实现大小写,则会导致编译器错误,指出该对象不符合协议

我已经阅读了文档,我能找到的唯一与可编码和可解码协议相关的东西是实现func encodeto encoder:encoder和initfrom decoder:decoder函数的要求

我得到的最接近的结果是定义一个协议,如下所示:

protocol TestProtocol {
    associatedType Keys: CodingKey
}
这要求实现者拥有一个符合CodingKey的Keys属性,但并不强制要求所有属性都有一个case。此外,您不能像使用Codable一样将Keys属性声明为private

可编码和编码键的处理是否比通过API公开的内容更深入


如果没有,是否有办法在Codable之外实现CodingKeys功能?

您会问两个问题。我会按顺序回答他们

可编码和编码键的处理是否比通过API公开的内容更深入

是的,Swift编译器知道可编码、可解码和编码密钥协议,并为它们编写了特殊代码

如果满足某些条件,编译器可以合成与CodingKey兼容的名为CodingKeys的枚举、initfrom:初始值设定项和encodeto:方法。这些条件在以下章节中详细说明:

对于某些类型,还可以自动合成可编码和可解码需求:

符合Encodable的类型(其属性都是可编码的)将获得自动生成的字符串支持的CodingKey枚举,并将属性映射到案例名称。类似地,对于属性都是可解码的可解码类型 类型分为1和类型,这些类型直接或通过typealias手动提供名为CodingKeys的CodingKey枚举,typealias的大小写按名称1对1映射到可编码/可解码属性,使用这些属性和键自动合成initfrom:和encodeto:(视情况而定) 如果需要,既不属于1也不属于2的类型必须提供自定义密钥类型,并根据需要提供自己的initfrom:和encodeto: 请注意,符合CodingKey的类型通常不必命名为CodingKey,甚至不必是enum,除非您依赖于编译器的一致性

此外,请注意,如果依赖编译器合成initfrom:或encodeto:,则符合CodingKey的CodingKeys类型只需要对其封闭类型的每个成员都有一个case

如果您手动实现initfrom:和encodeto:,那么您可以为符合CodingKey的类型使用任何名称,并且它只需要有您关心的情况。如果只使用单值容器或未指定的容器进行存储,则甚至不需要符合CodingKey的类型

如果没有,是否有办法在Codable之外实现CodingKeys功能

如果“功能性”指的是编译器自动合成实现的方式,那么唯一的方法就是使用Sourcery或gyb之类的代码生成器生成源代码并将其提供给编译器


如果“功能性”指的是编译器对封闭类型的每个可编码/可解码成员都需要一个键成员的方式,那么唯一的方法就是运行一个单独的程序,分析源代码并在缺少任何案例时排除错误。你不能让标准的Swift编译器为你做这件事。

你会问两个问题。我会按顺序回答他们

可编码和编码键的处理是否比通过API公开的内容更深入

是的,Swift编译器知道可编码、可解码和编码密钥协议,并为它们编写了特殊代码

如果满足某些条件,编译器可以合成与CodingKey兼容的名为CodingKeys的枚举、initfrom:初始值设定项和encodeto:方法。这些条件在以下章节中详细说明:

对于某些类型,还可以自动合成可编码和可解码需求:

符合Encodable的类型(其属性都是可编码的)将获得自动生成的字符串支持的CodingKey枚举,并将属性映射到案例名称。类似地,对于属性都是可解码的可解码类型 类型分为1和类型,这些类型直接或通过typealias手动提供名为CodingKeys的CodingKey枚举,typealias的大小写按名称1对1映射到可编码/可解码属性,使用这些属性和键自动合成initfrom:和encodeto:(视情况而定) 如果需要,既不属于1也不属于2的类型必须提供自定义密钥类型,并根据需要提供自己的initfrom:和encodeto: 请注意,CodingKey是兼容的 类型通常不必命名为CodingKeys,甚至不必是enum,除非您依赖于编译器的一致性

此外,请注意,如果依赖编译器合成initfrom:或encodeto:,则符合CodingKey的CodingKeys类型只需要对其封闭类型的每个成员都有一个case

如果您手动实现initfrom:和encodeto:,那么您可以为符合CodingKey的类型使用任何名称,并且它只需要有您关心的情况。如果只使用单值容器或未指定的容器进行存储,则甚至不需要符合CodingKey的类型

如果没有,是否有办法在Codable之外实现CodingKeys功能

如果“功能性”指的是编译器自动合成实现的方式,那么唯一的方法就是使用Sourcery或gyb之类的代码生成器生成源代码并将其提供给编译器


如果“功能性”指的是编译器对封闭类型的每个可编码/可解码成员都需要一个键成员的方式,那么唯一的方法就是运行一个单独的程序,分析源代码并在缺少任何案例时排除错误。你不能让标准Swift编译器为你做这件事。

谢谢,这是我要找的解释。谢谢,这是我要找的解释。