如果我想从 Codable 中排除某些属性,为什么这些属性必须是可选的?

Che*_*eng 4 swift codable

我有以下内容struct

struct Checklist : Codable {
    let id: Int64
    var text: String?
    var checked: Bool
    var visible: Bool
    var version: Int64

    private enum CodingKeys: String, CodingKey {
        case id
        case text
        case checked
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我收到编译器错误

类型“清单”不符合“可解码”协议

我可以解决的唯一方法是将排除的属性更改为可选。

struct Checklist : Codable {
    let id: Int64
    var text: String?
    var checked: Bool
    var visible: Bool?
    var version: Int64?

    private enum CodingKeys: String, CodingKey {
        case id
        case text
        case checked
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以知道为什么会这样吗?这是解决此类编译器错误的唯一正确方法吗?

Mar*_*n R 6

它们不必是可选的,但它们必须有一些初始值,例如

struct Checklist : Codable {
    let id: Int64
    var text: String?
    var checked: Bool
    var visible: Bool = false
    var version: Int64 = 0

    private enum CodingKeys: String, CodingKey {
        case id
        case text
        case checked
    }
}
Run Code Online (Sandbox Code Playgroud)

否则,当通过合成从外部表示创建实例时,这些属性将是未定义的

init(from decoder: Decoder)
Run Code Online (Sandbox Code Playgroud)

方法。或者,您可以自己实现该方法,确保所有属性都已初始化。

选项具有隐式初始值nil,这就是您的解决方案也有效的原因。

  • @cheok-yan- Cheng,很少解释为什么会发生这种情况:基本上,当您声明类型“Decodable”(“Codable”同时是“Decodable”和“Encodable”)时,会创建隐式“构造函数”来初始化字段使用解码器。如果您有“CodingKey”枚举,它将仅使用指定的字段,而其余字段将在该隐式构造函数中被忽略,因此它们不会设置任何值。 (2认同)