如何在Swift语言的字典中添加不同的types?

Swift只允许一个字典包含一个types。

这里是从Swift书中取得的定义:

字典是存储相同types的多个值的容器

[…]

它们不同于Objective-C的NSDictionaryNSMutableDictionary类,它们可以使用任何types的对象作为它们的键和值,并且不提供关于这些对象的性质的任何信息。

如果是这样的话,我们将如何创build嵌套字典?

想象一下,我们有一个plist ,它包含String,Array和Dictionary项目。 如果我被允许只持有相同types的项目(string,数组等),那么我将如何使用存储在plist中的不同types的项目?

我如何在Swift中的不同types的字典?

您可以使用Anytypes的字典值来实现类似plist的嵌套结构,这是Swift与Objective-C的idtypes相对应的,但也可以包含值types。

 var response = Dictionary<String, Any>() response["user"] = ["Login": "Power Ranger", "Password": "Mighty Morfin'"] response["status"] = 200 

编辑:

Any似乎都比AnyObject好,因为在上面的代码中, response["status"]Swift.Inttypes,而使用AnyObject值types时,它是__NSCFNumber

如上所述,您可以使用Anytypes来表示plist字典的值。 但是,你如何处理这些数据呢? 每次从字典中查找时都会抛出每个值? 这真是太麻烦了。 对plistbuild模的更好,更安全的方法是利用Swift的枚举,也就是所谓的代数数据types或歧视联合。 他们让你指定字典中允许的types,避免不必要的投射。 这是一个实现,解释如下:

 // An atomic (ie non-collection) data type in a plist. enum PListNode { case PLN_String(String) case PLN_Integer(Int) case PLN_Float(Double) case PLN_Bool(Bool) case PLN_Date(CFDate) case PLN_Data(CFData) } 

在最primefaces级别,只有上述数据types可以存储在plist中。 plist中的每个“节点”最终只能是这些types之一。 所以我们创build一个让我们指定这个的枚举。

 // A value that can be stored in a plist Dictionary's key-value pair. enum PListValue { case PLV_Node(PListNode) case PLV_Array(PListNode[]) case PLV_Dictionary(Dictionary<String, Box<PListValue>>) } typealias PList = Dictionary<String, Box<PListValue>> 

plist基本上是一个键 – 值对的字典, 每个值可以是primefaces(即非集合)值; 或者它可以是一个primefaces值的数组; 或者它可以是stringplist值对的字典。 上面的枚举表示这些约束,并且typealias给plisttypes一个易记的名字。

鉴于上述types,我们可以以types安全的方式完整地表示任何plist 例如:

 // Example translated from // https://developer.apple.com/library/Mac/documentation/Darwin/Reference/ManPages/man5/plist.5.html let myPlist: PList = [ "Year Of Birth": Box(PLV_Node(PLN_Integer(1965))) , "Pets Names": Box(PLV_Array([])) , "Picture": Box(PLV_Node(PLN_Data(...))) , "City of Birth": Box(PLV_Node(PLN_String("Springfield"))) , "Name": Box(PLV_Node(PLN_String("John Doe"))) , "Kids Names": Box( PLV_Array([PLN_String("John"), PLN_String("Kyra")]) ) ] 

这里的types安全意味着你可以使用switch语句处理任何给定的plist,并覆盖所有的可能性,而不需要任何铸造。 您正在消除一整类潜在的运行时错误。 例如:

 // See https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Enumerations.html#//apple_ref/doc/uid/TP40014097-CH12-XID_189 for explanation switch myPlist["Year Of Birth"] { case Box(.PLV_Node(let plvNodeValue)): ... case Box(.PLV_Array(let plvArrayValue)): ... case Box(.PLV_Dictionary(let plvDictionaryValue)): ... } 

请注意,有必要将recursion数据结构包装在一个“盒子”(一个指向实际值的指针)中,以保持其大小有限。

NSObject适用于我的情况,而“Any”不适用

 var d:Dictionary<String,NSObject> = [:] d["key1"] = "ddd" d["key2"] = 111 //OK NSLog("%@", d) //OK var d2:Dictionary = Dictionary<String,Any>() d2["key1"] = "ddd" d2["key2"] = 111 NSLog("%@", d2) //I got error here 

使用:Dictionary <String,AnyObject>

 var dict: Dictionary<String, AnyObject> = [ "number": 1, "string": "Hello", ] 

像这样使用NSMutableDictionary:

 var dictInfo : NSMutableDictionary = [ "lang_key": "1"] dictInfo["food_type"] = lbl_TypeOfFood.text dictInfo["search_text"] = txt_Search.text dictInfo["date"] = lbl_Date.text dictInfo["opening_hours"] = lbl_OpeningHours.text 

希望这将工作正常。

字典的NSMutableDictionary就像一个魅力,并允许你在Swift语言的字典中放入不同的types:

 let nsMutableDictionary = NSMutableDictionary() nsMutableDictionary[NSFontAttributeName] = UIFont(name: "HelveticaNeue", size: 12.0)! nsMutableDictionary[NSForegroundColorAttributeName] = UIColor.redColor() let dictionary: Dictionary<NSObject, AnyObject> = nsMutableDictionary self.attributedPlaceholder = NSAttributedString(string: textParam, attributes: dictionary) 
 let dictionary : Dictionary = [ "key": "value", "key2": 2, "key3": NSString(), 2: "test", ] 

可以指定限制字典的types

 let dictionary : Dictionary<String, String> = [ "key": "value", "key2": 2, // This errors ]