我正在努力编写一个编码以下结构的函数:
struct Lookup: Encodable {
var id: Int
var name: String
enum StateCodingKeys: String, CodingKey {
case id = "stateId"
case name = "stateName"
}
enum CityCodingKeys: String, CodingKey {
case id = "cityId"
case name = "cityName"
}
func encode(to encoder: Encoder, type: StateCodingKeys.Type) throws {
var container = encoder.container(keyedBy: type)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
}
}
这里的自定义encode
函数以StateCodingKeys.Type
为参数,但我找不到让这个函数接受任何CodingKey
类型的方法,比如CityCodingKeys
枚举,有办法做到吗?
您可以为两个枚举创建一个通用协议,将所需的枚举用例添加为static var
s,并使枚举符合协议。
protocol LookupCodingKey: CodingKey {
static var id: Self { get }
static var name: Self { get }
}
enum StateCodingKeys: String, LookupCodingKey {
case id = "stateId"
case name = "stateName"
}
enum CityCodingKeys: String, LookupCodingKey {
case id = "cityId"
case name = "cityName"
}
然后您可以添加协议作为通用约束:
func encode<CodingKeyType: LookupCodingKey>(to encoder: Encoder, type: CodingKeyType.Type) throws {
var container = encoder.container(keyedBy: type)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
}
旁注:
如果你只想直接调用encode(to:type:)
来编码Lookup
,我建议你不要遵守Encodable
,因为Lookup
会有一个生成的encode(to:)
方法,它不会调用你的encode(to:type:)
。
当您意外地将Lookup
传递给某个需要Encodable
的对象,并且某个对象使用encode(to:)
对其进行编码时,它将具有意外的密钥id
和name
。
我还没有尝试过,但您可能能够遵循EncodableWithConfiguration
,配置是编码密钥的类型。