我想在类播放器中使用JSONEncoder,它是在课后继承的。我得到错误“类型'Player.Type‘不能符合’可编码‘”。我找到了一些解决方案,但在这些情况下,JSON代码类似于使Person的变量类型。
人:
class Person: Codable {
let name: String
let surname: String
let gender: Bool
init(name: String, surname: String, gedner: Bool) throws {
self.name = name
self.surname = surname
self.gender = gedner
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
surname = try container.decode(String.self, forKey: .surname)
gender = try container.decode(Bool.self, forKey: .gender)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.name, forKey: .name)
try container.encode(self.surname, forKey: .surname)
try container.encode(self.gender, forKey: .gender)
}
private enum CodingKeys: String, CodingKey {
case name
case surname
case gender
}
}播放器:
class Player: Person {
private(set) var number: Int
init(name: String, surname: String, gedner: Bool, number: Int) throws {
self.number = number
try super.init(name: name, surname: surname, gedner: gedner)
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.number = try container.decode(Int.self, forKey: .number)
try super.init(from: decoder)
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(number, forKey: .number)
try container.encode(name, forKey: .name)
try container.encode(surname, forKey: .surname)
try container.encode(gender, forKey: .gender)
}
private enum CodingKeys: String, CodingKey {
case number
case name
case surname
case gender
}
}代码:
let newPlayer = try Player(name: "Name", surname: "Surname", gedner: true, number: 21)
let data = try encoder.encode(Player) //Error: Type 'Player.Type' cannot conform to 'Encodable'发布于 2022-04-25 22:55:34
为了澄清罗布说了些什么,再加上几个建议:
let newPlayer = try Player(name: "Name", surname: "Surname", gedner: true, number: 21)
let encoder = JSONEncoder()
// Provide object
let data = try encoder.encode(newPlayer)
let decoder = JSONDecoder()
// Provide type (and data)
let decodedPlayer = try decoder.decode(Player.self, from: data)Person中描述的那样简单,那么Person不需要任何自定义编码/解码,您可以依赖于合成的编码/解码:class Person: Codable {
let name: String
let surname: String
let gender: Bool
init(name: String, surname: String, gedner: Bool) throws {
self.name = name
self.surname = surname
self.gender = gedner
}
}上述代码将生成与自定义代码相同的编码/解码。
super.init一样,使用super.encode。所以代码变成:class Player: Person {
private(set) var number: Int
init(name: String, surname: String, gedner: Bool, number: Int) throws {
self.number = number
try super.init(name: name, surname: surname, gedner: gedner)
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.number = try container.decode(Int.self, forKey: .number)
try super.init(from: decoder)
}
override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(number, forKey: .number)
}
private enum CodingKeys: String, CodingKey {
case number
}
}与编码/解码无关
如评论中提到的@LeoDabus所述,Player.init(name: String...中的
init在Person中会抛出任何异常,因此您可能希望从Person.init和throws中删除throws您还可能希望将参数名从gender更正为
class Person: Codable {
let name: String
let surname: String
let gender: Bool
init(name: String, surname: String, gender: Bool) {
self.name = name
self.surname = surname
self.gender = gender
}
}和
class Player: Person {
private(set) var number: Int
init(name: String, surname: String, gender: Bool, number: Int) {
self.number = number
super.init(name: name, surname: surname, gender: gender)
}
// ...https://stackoverflow.com/questions/72006306
复制相似问题