诺亚的解释是正确的。这是错误的常见来源,并且由于可编码合成的“神奇”行为,发生的情况并不是立即显而易见的,这就是为什么我添加了这个警告 https://github.com/apple/swift/pull/30218给编译器,因为它让您注意到该属性不会被解码,并让您明确地调用它(如果这是预期的行为)。
正如修复程序所解释的那样,如果您想消除此警告,您有多种选择 - 您选择哪一个取决于您想要的具体行为:
- 通过一个传递初始值
init
:
struct ExampleItem: Decodable {
let number: Int
init(number: Int = 42) {
self.number = number
}
}
这将允许number
被解码,但你也可以传递实例ExampleItem
其中使用默认值。
也可以直接在里面使用init
相反,在解码期间:
struct ExampleItem: Decodable {
let number: Int
private enum CodingKeys: String, CodingKey {
case number
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
number = try container.decodeIfPresent(Int.self, forKey: .number) ?? 42
}
}
这将允许number
要解码,但使用42
如果解码失败则作为默认值。
- 使该物业成为
var
,尽管您也可以将其设为private(set) var
:
struct ExampleItem: Decodable {
var number: Int = 42
}
使其成为var
会允许number
被解码,但它也将允许调用者修改它。通过将其标记为private(set) var
相反,如果您愿意,您可以禁止此操作。
- 定义一个显式的
CodingKeys
enum:
struct ExampleItem: Decodable {
let number: Int = 42
private enum CodingKeys: CodingKey {}
}
这将防止number
免遭解码。由于枚举没有大小写,这可以让编译器清楚地知道没有要解码的属性。