考虑以下事项:
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
}
编译器提供两个错误
然而,A和B都是可编码的。如何解决/避免这些错误?
EDITED
由于Codable
的自动合成不起作用,我手动实现了所需的方法。
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)
}
}
现在它出现了新的错误
答案 0 :(得分:1)
协议不告诉编译器如何编码/解码符合它的类/结构。您需要为编译器实现协议,以完全了解如何初始化C结构的实例。
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)
}
}
答案 1 :(得分:0)
您应该在 struct C 中实现 init(来自解码器:解码器)和编码(到编码器:编码器),因为这些是必需的 Codable (可解码和可编码)协议使用。
public init(from decoder: Decoder) throws{
}
public func encode(to encoder: Encoder) throws{
}
<强> EDITED 强>
在Swift协议中,它不会向自己确认,因此您应该在协议A中使用 associatedtype 来确认协议B.
为了更好地理解协议,请阅读此答案。
https://stackoverflow.com/a/43408193/6303078
protocol B: Codable {
var text: String { get }
}
protocol A: Codable {
associatedtype CodableType : B
var b: CodableType { get }
var num: Int { get }
}
struct D: B {
var text: String
}
struct C<ElementType:B> : A{
typealias CodableType = ElementType
var b: CodableType
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)
b = try values.decode(CodableType.self, forKey: .b)
}
public 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)
}
}