可编码:扁平化结构

wad*_*dda 2 swift codable

假设我有某种具有 JSON 表示形式的类型:

{
  "count": 3,
  "name": "Pianos",
  "type": "instrument",
  "id": 1,
}
Run Code Online (Sandbox Code Playgroud)

假设我想将其表示为一个 Swift 对象,如下所示:

struct SomeObject: Codable { // this is the object I'd like to represent
  let id: Int
  let details: SomeDetails
}

struct SomeDetails: Codable {
  let count: Int
  let name: String
  let type: String
}
Run Code Online (Sandbox Code Playgroud)

解码这个对象是轻而易举的事。但是,在此实例中编码如何工作,以便我可以编码为平面结构——与我用来创建此对象并在上面的 JSON 示例中共享的结构相同?

Jos*_*yMW 8

对之前答案的改进。无需手动编码或解码其他对象,您只需转发初始化程序即可。

struct SomeDetails: Codable {
  let count: Int
  let name: String
  let type: String
}

struct SomeObject: Codable {
  enum CodingKeys: String, CodingKey {
    case id
  }

  let id: Int
  let details: SomeDetails

  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    id = try container.decode(Int.self, forKey: .id)
    details = try SomeDetails(from: decoder)
  }

  func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(id, forKey: .id)
    try details.encode(to: encoder)
  }
}
Run Code Online (Sandbox Code Playgroud)

对于一些额外的糖,您可以使用 Swift 5s 动态成员查找,以便您可以很好地访问这些成员object.name

@dynamicMemberLookup
struct SomeObject {
  ...

  subscript<T>(dynamicMember member: KeyPath<SomeDetails, T>) -> T {
    details[keyPath: member]
  }
}
Run Code Online (Sandbox Code Playgroud)