您能否“扩展”(即添加额外的初始化逻辑)可编码对象的自动生成的构造函数



当您在对象上实现Codable时,编译器可以自动生成构造函数。但是,仅当您尚未编写自己接受解码器的初始值设定项时,它才会执行此操作。

也就是说,我们有一个对象,其中包含从解码器设置的 ~50 个let属性,但我们也有五个基于这些let属性的计算属性。

从技术上讲,如果我们可以在初始值设定项中计算它们,那么在解码器设置了其他 50 个之后,我们可以简单地将结果存储在它们自己的let变量中,从而完全消除了对计算属性的需求。

问题是,如前所述,如果您实现自己的初始值设定项,编译器不会为您自动生成一个初始值设定项,因此您不仅要初始化"计算"值,还要初始化所有值。

那么有没有办法将自己作为初始化/解码过程的一部分插入,而不必自己完全重写初始值设定项?

您要查找的内容类似于委托模式,其中解码器通知其委托器已完成解码。可悲的是,它还没有添加到 Swift 中。我能想到的最接近的是使用继承,以便 Swift 可以为基类中的这 50 个let自动生成解码器,并且您可以在子类中初始化计算属性。例如:

class A: Decodable {
    let firstName: String
    let lastName: String
}
class B: A {
    private var _fullName: String! = nil
    var fullName: String { return _fullName }
    required init(from decoder: Decoder) throws {
        try super.init(from: decoder)
        _fullName = firstName + " " + lastName
    }
}

在类 A 中定义 50 个属性,并将所有计算属性保留在类 B 中。


或者根据您的建议,您也可以使用 lazy var

struct Model: Decodable {
    let firstName: String
    let lastName: String
    // private(set) so users cannot change value of the
    // pre-computed property
    lazy private(set) var fullName = self.firstName + " " + self.lastName
}
// But you can't use a let here, since calling fullName
// for the first time will mutate the struct
var model = try JSONDecoder().decode(Model.self, from: json)

相关内容

  • 没有找到相关文章

最新更新