在初始化所有存储的属性之前由于自身导致的自定义解码器错误
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)
}
}
以上无法编译,因为我在初始化所有存储的属性之前尝试同时使用 sort
和 compute(from:)
。
'self' used before all stored properties are initialized.
为了解决这个问题,我确实可以在 init(from:)
解码器的两个方法中移动逻辑。我会避免它,因为 VideoResponse
可以用作普通的 struct
.
extension VideoReponse {
init(videos: [Videos]) {
// same setup here...
}
}
知道如何解决这个问题以避免代码重复吗?
我的建议:
- 声明
lastVideos
为懒惰
- 使用内置 API
排序
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 sort
和 computeLastVideos
根本不会 访问 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
如果 sort
和 computerLastVideos
确实 访问 self
但是,你运气不好,必须 videos
一个非let
,先初始化,以后再改。您不能向 Swift 保证 sort
和 computeLastVideos
将 仅访问 self
.[=28= 的初始化部分 ]
我有以下 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)
}
}
以上无法编译,因为我在初始化所有存储的属性之前尝试同时使用 sort
和 compute(from:)
。
'self' used before all stored properties are initialized.
为了解决这个问题,我确实可以在 init(from:)
解码器的两个方法中移动逻辑。我会避免它,因为 VideoResponse
可以用作普通的 struct
.
extension VideoReponse {
init(videos: [Videos]) {
// same setup here...
}
}
知道如何解决这个问题以避免代码重复吗?
我的建议:
- 声明
lastVideos
为懒惰 - 使用内置 API 排序
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 sort
和 computeLastVideos
根本不会 访问 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
如果 sort
和 computerLastVideos
确实 访问 self
但是,你运气不好,必须 videos
一个非let
,先初始化,以后再改。您不能向 Swift 保证 sort
和 computeLastVideos
将 仅访问 self
.[=28= 的初始化部分 ]