在初始化所有存储的属性之前由于自身导致的自定义解码器错误

Custom Decoder error due to self before all stored properties are initialized

我有以下 Decodable 型号:

struct VideoResponse: Decodable {
    let videos: [Video]
    let lastVideos: [Video]

    enum CodingKeys: String, CodingKey {
        case videos
    } 

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
    
        let videos = try container.decode([Video].self, forKey: .videos)
        self.videos = sort(videos)
        self.lastVideos = computeLastVideos(from: self.videos)
    }
}

以上无法编译,因为我在初始化所有存储的属性之前尝试同时使用 sortcompute(from:)

'self' used before all stored properties are initialized.

为了解决这个问题,我确实可以在 init(from:) 解码器的两个方法中移动逻辑。我会避免它,因为 VideoResponse 可以用作普通的 struct.

extension VideoReponse {
    init(videos: [Videos]) { 
        // same setup here...
    }
}

知道如何解决这个问题以避免代码重复吗?

我的建议:

  1. 声明 lastVideos 为懒惰
  2. 使用内置 API
  3. 排序

struct VideoResponse: Decodable {
    let videos: [Video]
    lazy var lastVideos : [Video] = {
       return self.computeLastVideos(from: self.videos)
    }()

    enum CodingKeys: String, CodingKey { case videos } 

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)        
        self.videos = try container.decode([Video].self, forKey: .videos).sorted(by: { ... })
    }
}

您不能在存储的属性全部初始化之前调用 self 上的方法,因为这些方法可能会访问未初始化的 属性(另请参阅 this answer of mine),谁知道呢那会发生吗?你可以告诉 Swift sortcomputeLastVideos 根本不会 访问 self ]:

static func sort(_ videos: [Video]) -> [Video] { ... }
static func computeLastVideos(from videos: [Video]) -> [Video] { ... }

您还必须先将排序后的视频放入临时变量 sortedVideos,因为您无法访问 self.videos:

let container = try decoder.container(keyedBy: CodingKeys.self)
let videos = try container.decode([Video].self, forKey: .videos)
let sortedVideos = VideoResponse.sort(videos)
self.lastVideos = VideoResponse.computeLastVideos(from: sortedVideos)
self.videos = sortedVideos

如果 sortcomputerLastVideos 确实 访问 self 但是,你运气不好,必须 videos一个非let,先初始化,以后再改。您不能向 Swift 保证 sortcomputeLastVideos 仅访问 self.[=28= 的初始化部分 ]