排除不需要更改的 CodingKeys?

Exclude CodingKeys that doesn't need to be altered?

假设我有一个 struct User 模型,其中有很多属性。

struct User: Codable {
    let firstName: String
    let lastName: String
    // many more properties...
}

如你所见,它符合Codable。想象一下,如果 lastName 属性 应该是 encoded/decoded 作为 secondName 并且我想在最后将它保持为 lastName,我需要添加 CodingKeysUser 模型。

struct User: Codable {
    //...
    private enum CodingKeys: String, CodingKey {
        case firstName
        case lastName = "secondName"
        // all the other cases...
    }
}

有没有办法避免像上例中的firstName一样,在CodingKeys中包含所有与rawValue具有相同值的cases(感觉多余的)?我知道如果我在 CodingKeys 中避免使用 cases,那么在 decoding/encoding 中它不会被包含在内。但是,有什么方法可以覆盖这种行为吗?

目前没有这样的功能。但是您可以利用计算属性并制作原始属性 private.

struct User: Codable {
    var firstName: String
    private var secondName: String
    var lastName: String { 
        get { secondName }
        set { secondName = newValue }
    }
}

因此根本不需要手动实施 CodingKeys,它的行为完全符合您的喜好。看看他们的同行:

有一种可编码的方法,但好处值得怀疑。

创建通用 CodingKey

struct AnyKey: CodingKey {
    var stringValue: String
    var intValue: Int?

    init?(stringValue: String) { self.stringValue = stringValue; self.intValue = nil }
    init?(intValue: Int) { self.stringValue = String(intValue); self.intValue = intValue }
}

并添加自定义 keyDecodingStrategy

struct User: Codable {
    let firstName: String
    let lastName: String
    let age : Int
}

let jsonString = """
{"firstName":"John", "secondName":"Doe", "age": 30}
"""

let data = Data(jsonString.utf8)

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .custom({ keyPath -> CodingKey in
        let key = keyPath.last!
        return key.stringValue == "secondName" ? AnyKey(stringValue:"lastName")! : key
    })
    let result = try decoder.decode(User.self, from: data)
    print(result)
} catch {
    print(error)
}