如何在Swift语言的词典中输入不同的类型?

如何在Swift语言的词典中输入不同的类型?,swift,dictionary,Swift,Dictionary,Swift只允许字典包含单个类型 以下是取自Swift手册的定义: 字典是存储相同类型的多个值的容器 [……] 它们不同于Objective-C的NSDictionary和NSMutableDictionary类,后者可以使用任何类型的对象作为键和值,并且不提供有关这些对象性质的任何信息 如果是这样,那么我们将如何创建嵌套字典 假设我们有一个plist,其中包含字符串、数组和字典项。如果只允许保存相同类型的项(字符串、数组等),那么如何使用plist中存储的不同类型的项 在Swift中,如何在同

Swift只允许字典包含单个类型

以下是取自Swift手册的定义:

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

[……]

它们不同于Objective-C的
NSDictionary
NSMutableDictionary
类,后者可以使用任何类型的对象作为键和值,并且不提供有关这些对象性质的任何信息

如果是这样,那么我们将如何创建嵌套字典

假设我们有一个
plist
,其中包含字符串、数组和字典项。如果只允许保存相同类型的项(字符串、数组等),那么如何使用plist中存储的不同类型的项

在Swift中,如何在同一本词典中输入不同的类型

let dictionary : Dictionary = [
    "key": "value",
    "key2": 2,
    "key3": NSString(),
    2: "test",
]
可以指定限制字典的类型

let dictionary : Dictionary<String, String> = [
    "key": "value",
    "key2": 2, // This errors
]
let字典:字典=[
“键”:“值”,
“key2”:2,//此错误
]

您可以使用
任何
字典值类型实现类似plist的嵌套结构,该类型在某种程度上与Objective-C的
id
类型相对应,但也可以保存值类型

var response = Dictionary<String, Any>()
response["user"] = ["Login": "Power Ranger", "Password": "Mighty Morfin'"]
response["status"] = 200
var response=Dictionary()
响应[“用户”]=[“登录”:“强力护林员”,“密码”:“强力莫芬”]
响应[“状态”]=200
编辑:

Any
似乎比
AnyObject
好,因为在上面的code
响应中[“status”]
是类型
Swift.Int
,而使用值类型
AnyObject
则是
\NSCFNumber

使用:字典

var dict:Dictionary=[
“数字”:1,
“字符串”:“你好”,
]

正如所建议的,您可以使用
Any
类型来表示plist字典的值。但是你如何处理这些数据呢?每次从字典中查找时都要转换每个值?那真是一团糟。对plist进行建模的更好、更安全的方法是利用Swift的枚举,也称为代数数据类型或判别联合。它们允许您精确地指定字典中允许的类型,并避免强制转换。下面是一个实现,解释如下:

// An atomic (i.e. 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)
}
在大多数原子级别上,只有上述数据类型可以存储在plist中。plist中的每个“节点”最终只能是这些类型中的一种。所以我们创建了一个枚举,让我们可以指定它

// 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>>
这里的类型安全意味着,您可以使用
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)):
    ...
}

请注意,有必要将递归数据结构封装在“框”(指向实际值的指针)中,以保持其大小有限。

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

vard:Dictionary=[:]
d[“键1”]=“ddd”
d[“键2”]=111//OK
NSLog(“%@”,d)//确定
变量d2:Dictionary=Dictionary()
d2[“键1”]=“ddd”
d2[“键2”]=111
NSLog(“%@”,d2)//我在这里遇到了错误

NSMutableDictionary-to-Dictionary的工作方式就像一个符咒,可以让您在一本使用Swift语言的词典中输入不同的类型:

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)
让nsMutableDictionary=nsMutableDictionary()
nsMutableDictionary[NSFontAttributeName]=UIFont(名称:“HelveticaNeue”,大小:12.0)!
nsMutableDictionary[NSForegroundColorAttributeName]=UIColor.redColor()
let dictionary:dictionary=nsMutableDictionary
self.attributedPlaceholder=NSAttributedString(string:textParam,attributes:dictionary)

像这样使用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

希望这可以正常工作。

更多信息如果类型数量受到限制,最好使用公共协议(例如
PropertyListType
,使用扩展添加到类型中)组合允许的类型(本例中为属性列表类型),并声明字典仅包含这些类型
dictionary
。这种方法将有助于维护类型安全。@NikolaiRuhe您能详细说明一下吗?如何创建这样的协议?我在文档中找不到任何东西。谢谢!:)@我是否认为@Nikolai Ruhe的意思是
协议类型
,你可以在Swift书籍中找到更多信息:为什么有人会下载这个问题?有什么问题吗?我可以想象,因为标题含糊不清。这不起作用,会抛出一个错误“无法将“Dictionary”类型的表达式转换为“StringLiteralConvertible”类型。它的工作方式很有魅力,回答了这个问题,那么为什么要进行向下投票呢?我建议人们使用var d0/d1,因为所有框架都是基于零的。d2将是第三本字典。这应该是公认的答案;这是唯一一个真正处理类型的。
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
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)
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