struct Person: Decodable {
let firstName: String
}
var data = """
{"firstName": "Fai"}
""".data(using: .utf8)!
let decoder = JSONDecoder()
let parsed = try decoder.decode(Person.self, from: data)
JSONDecoder
将对数据进行解码,该数据符合Decodable
协议。
所以我想知道如何快速实现这一点。但我不能得到任何想法的源代码:https://github.com/apple/swift/blob/main/stdlib/public/core/Codable.swiftDecodable
协议只需要实现一个init(from decoder: Decoder)
函数,如果要做的话,我会对struct做一个扩展:
extension struct: Decodable {
init(from decoder: Decoder) {...}
}
但是当我删除示例中的Decodable时,编译器会给予错误:
示例方法“decode(_:from:)”要求“Person”符合“Decodable”
所以这不是实现这个的快捷方式。快捷方式怎么样?源代码在哪里?
2条答案
按热度按时间ff29svar1#
您可以看到编译器使用
-print-ast
为您编写的内容:这将输出大部分自动生成的代码(它应该包括所有的Codable一致性,但是还有一些其他类型的自动生成代码不包括它们的实现):
有关完整的实现细节,请参见DerivedConformanceCodable.cpp。您最感兴趣的问题可能是
deriveBodyDecodable_init
。nxagd54h2#
Swift会自动为没有自定义实现init(from:)初始化器的结构体合成Decodable协议,这意味着你可以使用一个结构体作为Decodable类型,而无需自己实现init(from:)初始化器,只要该结构体的属性与编码数据中的键匹配。
例如,假设您有以下结构:
这个结构体符合Decodable协议,因为它没有init(from:)初始化器的自定义实现。当您尝试解码包含密钥id、name和email的数据时,Swift将自动使用User结构体的属性名称和类型来解码数据并创建一个新的User示例。
您可以使用JSONDecoder类的decode(_:from:)方法对数据进行解码,如下所示: