使 Swift Class 具有字符或基于字符的 属性 可编码
Making Swift Class With Character Or Character-Based Property Codable
Swift 4 中的字符 class 似乎没有实现 Codable 协议。我想了解这样做的理由,因为 class 似乎有资格作为 Swift.
中的基础 class
看看下面的(故意剥离的)递归 class,在保留使用 Character 作为 Dictionary 键的同时使其可编码的最佳方法是什么?
class MyClass: Codable { <- does not compile
var myProperty: [Character: MyClass]?
var myOtherProperty: Int = 42
}
谢谢!
您可以使 Character
符合 Codable
协议,如下所示:
extension Character: Codable {
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
let string = try container.decode(String.self)
guard !string.isEmpty else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Decoder expected a Character but found an empty string.")
}
guard string.count == 1 else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Decoder expected a Character but found a string: \(string)")
}
self = string[string.startIndex]
}
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(String(self))
}
}
游乐场测试
let aClass = AClass()
let bClass = AClass()
bClass.myOtherProperty = 10
aClass.myProperty = [:]
aClass.myProperty?["B"] = bClass
aClass.myOtherProperty = 20
do {
let jsonData = try JSONEncoder().encode(aClass)
print(String(data: jsonData, encoding: .utf8)!) // "{"myProperty":[["B"],{"myOtherProperty":10}],"myOtherProperty":20}\n"
let decodedObject = try JSONDecoder().decode(AClass.self, from: jsonData)
print(decodedObject.myProperty) // "Optional(["B": __lldb_expr_73.AClass])\n"
print(decodedObject.myOtherProperty) // 20
} catch {
print(error)
}
Swift 4 中的字符 class 似乎没有实现 Codable 协议。我想了解这样做的理由,因为 class 似乎有资格作为 Swift.
中的基础 class看看下面的(故意剥离的)递归 class,在保留使用 Character 作为 Dictionary 键的同时使其可编码的最佳方法是什么?
class MyClass: Codable { <- does not compile
var myProperty: [Character: MyClass]?
var myOtherProperty: Int = 42
}
谢谢!
您可以使 Character
符合 Codable
协议,如下所示:
extension Character: Codable {
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
let string = try container.decode(String.self)
guard !string.isEmpty else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Decoder expected a Character but found an empty string.")
}
guard string.count == 1 else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Decoder expected a Character but found a string: \(string)")
}
self = string[string.startIndex]
}
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(String(self))
}
}
游乐场测试
let aClass = AClass()
let bClass = AClass()
bClass.myOtherProperty = 10
aClass.myProperty = [:]
aClass.myProperty?["B"] = bClass
aClass.myOtherProperty = 20
do {
let jsonData = try JSONEncoder().encode(aClass)
print(String(data: jsonData, encoding: .utf8)!) // "{"myProperty":[["B"],{"myOtherProperty":10}],"myOtherProperty":20}\n"
let decodedObject = try JSONDecoder().decode(AClass.self, from: jsonData)
print(decodedObject.myProperty) // "Optional(["B": __lldb_expr_73.AClass])\n"
print(decodedObject.myOtherProperty) // 20
} catch {
print(error)
}