[我是Swift的新手,我不知道这是否可能,所以请建议我]
我有一本字典(动态),如:
let simpleHash = ["testA": "A", "testB": "B", "testC": "C"]
我想将其转换为Object,以便我可以访问:
simpleHash.testA // instead of simpleHash["testA"]
我已经尝试了下面的一个,但它没有帮助
let jsonData = try JSONSerialization.data(withJSONObject: simpleHash, options: .prettyPrinted)
let decoded = try JSONSerialization.jsonObject(with: jsonData, options: [])
任何人都可以就此提出建议。 提前谢谢!
答案 0 :(得分:1)
Swift将需要为testA显式声明的变量,因此您将无法100%动态。但是,由于您需要在代码中使用变量,因此在某些时候将会知道它。鉴于此并且本着最小化声明约束的精神,您可以定义一个使用字典作为其内部存储的类,并将键值公开为计算属性。
这是一个例子:
class DictionaryBased
{
var content:[String:Any]
init(_ dictionary:[String:Any])
{ content = dictionary }
func get<T>(_ key:String, _ defaultValue:T) -> T
{ return content[key] as? T ?? defaultValue }
func set<T>(_ key:String, _ value:T)
{ content[key] = value }
}
class SimpleHash:DictionaryBased
{}
通过这种方式,您可以根据需要(以及需要时)使用扩展名添加计算属性。
extension SimpleHash
{
var testA:String { get { return get("testA", "") } set { set("testA",newValue) } }
var testB:String { get { return get("testB", "") } set { set("testB",newValue) } }
// if variables are "read-only", you don't need the set { } part
var testC:String { get { return get("testC", "") } }
}
您可以添加是否键入的变量并支持选项,或者(如上所述)提供默认值。
extension SimpleHash
{
var testD:Any? { get { return get("testD", nil) } set { set("testD",newValue) } }
var testE:String? { get { return get("testE", nil) } set { set("testE",newValue) } }
var testF:Date? { get { return get("testF", nil) } set { set("testE",newValue) } }
}
使用这个&#34;基于词典&#34;对象,你需要在某个时刻创建一个实例并给它字典的内容:
let simpleHash = SimpleHash(["testA": "A", "testB": "B", "testC": "C"])
simpleHash.testA // "A"
simpleHash.testD // nil
请注意,这并不像使用本机属性和将字典映射到每个物理变量一样高效。另一方面,这样的代码要少得多。如果不经常引用变量,则额外的开销可能是简单和灵活性的可接受的权衡。
答案 1 :(得分:0)
一个简单的struct
来保存您的Dictionary
值:
struct SimpleStruct {
// properties are Optional since they might not be matched
let testA: String?
let testB: String?
// this one has a default value
let testC: String
// init that takes a Dictionary
init(dictionary: [String:Any]) {
// set the Optional ones
self.testA = dictionary["testA"] as? String
self.testB = dictionary["testB"] as? String
// set the one with a default
self.testC = dictionary["testC"] as? String ?? "C"
}
}
let foo = SimpleStruct(dictionary: ["testA": "A", "testB": "B", "testC": "C"])
// force-unwrapping for brevity
// you should actually test before using
print(foo.testA!) // prints A
print(foo.testB!) // prints B
print(foo.testC) // prints C