[英]Swift 4 collection of Codable objects
我有一个Codable
类,其中包含一个包含String
键和值的字典,该String
可以是String
s, Int
s或符合Codable
自定义结构。 我的问题是:
如何定义具有可Codable
值的字典?
我希望这足以说明
var data: [String: Codable] = [:]
但显然这使我的班级不再符合Codable
。 我认为这里的问题与我在这里的问题相同,我传递协议而不是协议约束的对象
所以我可能需要一个约束泛型类型,比如AnyObject<Codable>
但这是不可能的。
编辑:答案
因此,由于这不能按照接受的答案进行,所以我使用的是每个数据类型都有字典的结构
struct CodableData {
var ints: [String: Int]
var strings: [String: String]
//...
init() {
ints = [:]
strings = [:]
}
}
var data = CodableData()
Swift集合只包含一种类型,并且对于它是Codable,该类型需要是Codable - 不是Codable类型,而是Codable协议的采用者 。 你需要这里的类型是一个特定的Codable采用者 。
因此,执行您所描述的内容的唯一方法是基本上发明一些新类型StringOrIntOrStruct,它包装String或Int或结构,并且本身采用Codable。
但我不认为你这样做,因为努力似乎不值得。 基本上,你应该首先停止尝试使用异构的Swift集合; 这完全违背了语言的精神。 从一开始就是一种糟糕的气味。 重新思考你的目标。
我认为编译器根本不够聪明,无法自动推断Codable
实现。 因此,一种可能的解决方案是手动实现Codable
:
class Foo: Codable {
var data: [String:Codable] = [:]
func encode(to encoder: Encoder) throws {
// ...
}
required init(from decoder: Decoder) throws {
// ...
}
}
我不知道您是否可以更改data
类型以帮助编译器为您完成工作。 至少你可以将手动编码拉到有问题的类型:
enum Option: Codable {
case number(Int)
case string(String)
func encode(to encoder: Encoder) throws {
// ...
}
init(from decoder: Decoder) throws {
if let num = try? Int(from: decoder) {
self = .number(num)
} else if let str = try? String(from: decoder) {
self = .string(str)
} else {
throw something
}
}
}
class Foo: Codable {
var data: [String:Option] = [:]
}
有没有人在Swift中尝试过Generics? 看:
public struct Response<T> where T : Codable {
let ContentEncoding : String?
let ContentType : String?
let JsonRequestBehavior : Int?
let MaxJsonLength : Int?
let RecursionLimit : Int?
let data : Data?
public struct Data : Codable {
let response : String?
let status : String?
let details : [T]?
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.