繁体   English   中英

Codable 和 CodingKeys

[英]Codable and CodingKeys

我正在尝试实现一个与Codable如何使用CodingKeys枚举具有类似功能的协议。

使用CodableCodingKeys ,如果您没有在CodingKeys枚举中为Codable对象上的每个属性实现 case,则会导致编译器错误,指出该对象不符合协议。

我查看了文档,唯一能找到的与Codable ( Encodable and Decodable ) 协议相关的是实现func encode(to encoder: Encoder)init(from decoder: Decoder)函数的要求。

我得到的最接近的是定义如下协议:

protocol TestProtocol {
    associatedType Keys: CodingKey
}

这要求实现者有一个符合CodingKeyKeys属性,但它并不强制要求所有属性都有一个案例。 此外,您不能像使用Codable一样将Keys属性声明为私有。

CodableCodingKeys处理的层次是否比通过 API 公开的更深?

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

你问两个问题。 我认为以相反的顺序解释它们会更容易。

Codable 和 CodingKeys 的处理层次是否比通过 API 公开的更深?

是的,Swift 编译器知道EncodableDecodableCodingKey协议,并为它们提供了特殊的代码。

如果满足某些条件,编译器可以合成一个名为CodingKeysCodingKeyenuminit(from:)初始化程序和encode(to:)方法。 SE-0166中详细说明了这些条件:

也可以为某些类型自动合成可Encodable和可Decodable要求:

  1. 符合Encodable其属性都是Encodable的类型会自动生成String支持的CodingKey enum映射属性到案例名称。 类似地,对于其属性都是DecodableDecodable类型
  2. 属于 (1) 的类型——以及手动提供CodingKey enum (直接命名为CodingKeys或通过typealias命名)的类型,其情况按名称一对一映射到Encodable / Decodable属性——自动合成init(from:)encode(to:)酌情使用这些属性和键
  3. 如果需要,既不属于 (1) 也不属于 (2) 的类型必须提供自定义键类型,并酌情提供它们自己的init(from:)encode(to:)

请注意,与CodingKey兼容的类型通常不必命名为CodingKeys甚至是enum ,除非您依赖编译器综合的一致性。

此外,请注意,如果您依赖编译器来合成init(from:)encode(to:) ,则符合CodingKeyCodingKeys类型只需要为其封闭类型的每个成员都有一个案例。

如果您手动实现init(from:)encode(to:) ,您可以为CodingKey的类型使用任何名称,并且它只需要包含您关心的情况。 如果您仅使用单值容器或无键容器进行存储,您甚至不需要CodingKey的类型。

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

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

如果“功能”是指编译器需要为封闭类型的每个Encodable / Decodable成员提供一个关键成员的方式,那么唯一的方法是运行一个单独的程序来分析您的源代码并在任何情况下排除错误失踪。 你不能让标准的 Swift 编译器为你做这件事。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM