我正在尝试实现一种协议,该协议的功能与Codable
使用CodingKeys
枚举的方式类似。
使用Codable
和CodingKeys
,如果您没有在CodingKeys
对象的每个属性的Codable
枚举中实现大小写,则会导致编译器错误,指出该对象不符合协议。
我仔细阅读了文档,发现与Codable
(Encodable
和Decodable
)协议相关的唯一内容是实现func encode(to encoder: Encoder)
和init(from decoder: Decoder)
个功能。
我最近得到的是定义一个协议,如下所示:
protocol TestProtocol {
associatedType Keys: CodingKey
}
这要求实现者具有符合Keys
的{{1}}属性,但并不强制要求所有属性都具有大小写。此外,您无法像使用CodingKey
一样声明Keys
属性为私有属性。
对Codable
和Codable
的处理程度是否比通过API暴露的程度还要深?
如果没有,是否可以在CodingKeys
之外实现CodingKeys
功能?
答案 0 :(得分:1)
您问两个问题。我会按顺序给他们答复。
Codable和CodingKeys的处理是否比API公开的要深?
是的,Swift编译器了解Encodable
,Decodable
和CodingKey
协议,并为它们提供了特殊的代码。
如果满足某些条件,则编译器可以合成名为CodingKey
的符合enum
的{{1}},CodingKeys
初始化程序和init(from:)
方法。条件在SE-0166中有详细说明:
encode(to:)
和Encodable
要求也可以针对某些类型自动合成:
- 所有属性均为
Decodable
的符合Encodable
的类型将获得一个自动生成的Encodable
支持的String
CodingKey
,将属性映射到案例名称。同样,对于属性全部为enum
的{{1}}类型的- 属于(1)的类型-手动提供{@ {1}}
Decodable
(直接或通过Decodable
命名的CodingKey
enum
)的类型映射为1-按名称从1到CodingKeys
/typealias
的属性-使用这些属性和键,适当地自动合成Encodable
和Decodable
- 既不属于(1)也不属于(2)的类型将必须提供自定义键类型,并根据需要提供自己的
init(from:)
和encode(to:)
请注意,除非您依靠编译器,否则符合init(from:)
的类型通常没有被命名为encode(to:)
甚至是CodingKey
。综合的一致性。
此外,请注意,如果您依赖编译器来合成CodingKeys
或{,则符合enum
的{{1}}类型的包围类型的每个成员都需要有一个大小写{1}}。
如果您要手动实现CodingKeys
和CodingKey
,则可以为您的init(from:)
兼容类型使用任何名称,并且只需要关心您的情况。如果仅使用单值容器或非键值容器进行存储,则甚至不需要encode(to:)
兼容类型。
如果没有,是否有办法在Codable之外实现CodingKeys功能?
如果用“功能”来表示编译器自动综合实现的方式,那么唯一的方法是使用代码生成器(如Sourcery或gyb)生成源代码并将其提供给编译器。
如果“功能性”是指编译器为封闭类型的每个init(from:)
/ encode(to:)
成员要求一个关键成员的方式,那么唯一的方法是运行一个单独的程序分析您的源代码,并在缺少任何情况的情况下出错。您无法让标准的Swift编译器为您完成此任务。