在 Swift 中将对象编码为字符串
我正在做的一个项目需要一个Codable对象可以表示为一个基本的文本字符串,具体来说不是一个JSON字符串。我最终找到了解决方案,所以想把它记录下来,部分是为了帮助有同样需求的人,也欢迎有人如果有更简单的方法可以纠正我。
假设你有这个结构体:
struct MyData {
let text: String
let number: Int
}
你想用以下格式编码数据:My text (12)
该Encodable其中一部分很简单,只需实现encode方法,并返回格式化字符串,并返回单值容器中的字符串:
extension MyData: Encodable {
func encode(to encoder: any Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode("\(text) (\(number))")
}
}
Decodable虽然工作量稍重,但也相当直接。我选择实现一个构造函数,可以从源字符串初始化结构体——使用正则表达式,因为我喜欢问题——然后它只是从解码初始化器中调用该初始化器,在提取单值容器之后:
extension MyData: Decodable {
init(from string: String) throws {
let regex = #/^(.+?) \(([\d]+)\)$/#
let result = try regex.wholeMatch(in: string)!
self.text = String(result.1) // convert to an owned String
self.number = Int(result.2)!
}
init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
let sourceString: String = try container.decode(String.self)
try self.init(from: sourceString)
}
}
虽然不需要这个额外的构造子,因为所有操作都可以在解码构造器里完成,但我觉得这样做方式很好。请注意,如果遇到格式不正确的字符串,这个程序会崩溃,所以设置正确的防护措施只能留给读者自己去做。
评论
?
参与讨论