编码键和编码键

时间:2019-04-16 02:08:28

标签: swift codable decodable encodable

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

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

我仔细阅读了文档,发现与CodableEncodableDecodable)协议相关的唯一内容是实现func encode(to encoder: Encoder)init(from decoder: Decoder)个功能。

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

protocol TestProtocol {
    associatedType Keys: CodingKey
}

这要求实现者具有符合Keys的{​​{1}}属性,但并不强制要求所有属性都具有大小写。此外,您无法像使用CodingKey一样声明Keys属性为私有属性。

CodableCodable的处理程度是否比通过API暴露的程度还要深?

如果没有,是否可以在CodingKeys之外实现CodingKeys功能?

1 个答案:

答案 0 :(得分:1)

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

  

Codable和CodingKeys的处理是否比API公开的要深?

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

如果满足某些条件,则编译器可以合成名为CodingKey的符合enum的{​​{1}},CodingKeys初始化程序和init(from:)方法。条件在SE-0166中有详细说明:

  

encode(to:)Encodable要求也可以针对某些类型自动合成:

     
      
  1. 所有属性均为Decodable的符合Encodable的类型将获得一个自动生成的Encodable支持的String CodingKey,将属性映射到案例名称。同样,对于属性全部为enum的{​​{1}}类型的
  2.   
  3. 属于(1)的类型-手动提供{@ {1}} Decodable(直接或通过Decodable命名的CodingKey enum)的类型映射为1-按名称从1到CodingKeys / typealias的属性-使用这些属性和键,适当地自动合成EncodableDecodable
  4.   
  5. 既不属于(1)也不属于(2)的类型将必须提供自定义键类型,并根据需要提供自己的init(from:)encode(to:)
  6.   

请注意,除非您依靠编译器,否则符合init(from:)的类型通常没有被命名为encode(to:)甚至是CodingKey。综合的一致性。

此外,请注意,如果您依赖编译器来合成CodingKeys或{,则符合enum的{​​{1}}类型的包围类型的每个成员都需要有一个大小写{1}}。

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

  

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

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

如果“功能性”是指编译器为封闭类型的每个init(from:) / encode(to:)成员要求一个关键成员的方式,那么唯一的方法是运行一个单独的程序分析您的源代码,并在缺少任何情况的情况下出错。您无法让标准的Swift编译器为您完成此任务。