Swift:对同一个可编码结构使用多个CodingKey类型



我正在努力编写一个编码以下结构的函数:

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 vars,并使枚举符合协议。

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:)对其进行编码时,它将具有意外的密钥idname

我还没有尝试过,但您可能能够遵循EncodableWithConfiguration,配置是编码密钥的类型。

最新更新