无法使用协议包含采用可编码协议 [英] Fail to use Protocol contains Protocol adopting Codable

查看:60
本文介绍了无法使用协议包含采用可编码协议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下内容:

protocol A: Codable {
  var b: B { get }
  var num: Int { get }
}
protocol B: Codable {
  var text: String { get }
}
struct C: A {
  var b: B
  var num: Int
}

编译器给出两个错误


  • 类型'C'不符合协议'可解码'

  • 类型'C '不符合协议'Encodable'。

但是A和B都是可编码的。如何解决/避免这些错误?

However Both A and B are Codable. How to solve/avoid these errors?

参考:

已编辑

EDITED

作为 Codable 不起作用,我手动实现了必需的方法。

As the auto-synthesis for Codable not working, I manually implemented the required methods.

struct C: A {
  var b: B
  var num: Int

  enum CodingKeys: String, CodingKey {
    case b
    case num
  }

  func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(num, forKey: .num)
    try container.encode(b, forKey: .b)
  }
  init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    num = try values.decode(Int.self, forKey: .num)
    b = try values.decode(B.self, forKey: .b)
  }
}

现在它给出了新的错误

推荐答案

协议没有不会告诉编译器如何对符合它的类/结构进行编码/解码。您需要为编译器提供协议的实现,以完全了解如何初始化C结构的实例。

A protocol doesn't tell the compiler how to encode/decode classes/structs that conforms to it. You need an implementation of the protocol for the compiler to fully understand how to init an instance of the C struct.

struct D: B {
  var text: String
}

struct C: A {
  var b: B
  var num: Int

  public init(from decoder: Decoder) throws {
    b = D(text: " ")
    num = 0
  }

  public func encode(to encoder: Encoder) throws {

  } 
}

protocol A: Codable {
  var b: B { get }
  var num: Int { get }
}
protocol B: Codable {
  var text: String { get }
}
struct D: B {
  var text: String
}

struct C: A {
  var b: B
  var num: Int

  enum CodingKeys: String, CodingKey {
    case b
    case num
  }

  public init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    num = try values.decode(Int.self, forKey: .num)
    let text = try values.decode(String.self, forKey: .b)
    b = D(text: text)
  }

  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(num, forKey: .num)
    try container.encode(b.text, forKey: .b)
  }
}

这篇关于无法使用协议包含采用可编码协议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆