# Swift字典字面量我们可以使用字典字面量来构造字典,它们和我们刚才介绍过的数组字面量拥有相似语法。一个字典字面量是一个定义拥有一个或者多个键值对的字典集合的简单语句。一个键值对是一个key和一个value的结合体。在字典字面量中,每一个键值对的键和值都由冒号分割。这些键值对构成一个列表,其中这些键值对由方括号包含并且由逗号分割: [key 1: value 1, key 2: value 2, key 3: value 3]下面的例子创建了一个存储国际机场名称的字典。在这个字典中键是三个字母的国际航空运输相关代码,值是机场名称: var airports: [String:String] = ["TYO": "Tokyo", "DUB": "Dublin"]`airports`字典被定义为一种 `[String: String]`,它意味着这个字典的键和值都是`String`类型。- 注意: `airports`字典被声明为变量(用`var`关键字)而不是常量(`let`关键字)因为后来更多的机场信息会被添加到这个示例字典中。`airports`字典使用字典字面量初始化,包含两个键值对。第一对的键是`TYO`,值是`Tokyo`。第二对的键是`DUB`,值是`Dublin`。这个字典语句包含了两个`String: String`类型的键值对。它们对应airports变量声明的类型(一个只有`String`键和`String`值的字典)所以这个字典字面量是构造两个初始数据项的`airport`字典。和数组一样,如果我们使用字面量构造字典就不用把类型定义清楚。`airports`的也可以用这种方法简短定义: var airports = ["TYO": "Tokyo", "DUB": "Dublin"]因为这个语句中所有的键和值都分别是相同的数据类型,Swift 可以推断出`Dictionary`是`airports`字典的正确类型。###读取和修改字典我们可以通过字典的方法和属性来读取和修改字典,或者使用下标语法。和数组一样,我们可以通过字典的只读属性count来获取某个字典的数据项数量: println("The dictionary of airports contains \(airports.count) items.") // 打印 "The dictionary of airports contains 2 items."(这个字典有两个数据项)可以使用布尔属性isEmpty来快捷的检查字典的count属性是否等于0。 if airports.isEmpty { println("The airports dictionary is empty.") } else { println("The airports dictionary is not empty.") } // 打印 "The airports dictionary is not empty.(这个字典不为空)"我们也可以在字典中使用下标语法来添加新的数据项。可以使用一个合适类型的 key 作为下标索引,并且分配新的合适类型的值: airports["LHR"] = "London" // airports 字典现在有三个数据项我们也可以使用下标语法来改变特定键对应的值: airports["LHR"] = "London Heathrow" // "LHR"对应的值 被改为 "London Heathrow作为另一种下标方法,字典的updateValue(forKey:)方法可以设置或者更新特定键对应的值。就像上面所示的示例,updateValue(forKey:)方法在这个键不存在对应值的时候设置值或者在存在时更新已存在的值。和上面的下标方法不一样,这个方法返回更新值之前的原值。这样方便我们检查更新是否成功。`updateValue(forKey:)`函数会返回包含一个字典值类型的可选值。举例来说:对于存储String值的字典,这个函数会返回一个String?或者“可选 String”类型的值。如果值存在,则这个可选值值等于被替换的值,否则将会是`nil`。 if let oldValue = airports.updateValue("Dublin Internation", forKey: "DUB") { println("The old value for DUB was \(oldValue).") } // 输出 "The old value for DUB was Dublin."(DUB原值是dublin)我们也可以使用下标语法来在字典中检索特定键对应的值。由于使用一个没有值的键这种情况是有可能发生的,可选类型返回这个键存在的相关值,否则就返回`nil`: if let airportName = airports["DUB"] { println("The name of the airport is \(airportName).") } else { println("That airport is not in the airports dictionary.") } // 打印 "The name of the airport is Dublin Internation."(机场的名字是都柏林国际)我们还可以使用下标语法来通过给某个键的对应值赋值为nil来从字典里移除一个键值对: airports["APL"] = "Apple Internation" // "Apple Internation"不是真的 APL机场, 删除它 airports["APL"] = nil // APL现在被移除了另外,removeValueForKey方法也可以用来在字典中移除键值对。这个方法在键值对存在的情况下会移除该键值对并且返回被移除的value或者在没有值的情况下返回nil: if let removedValue = airports.removeValueForKey("DUB") { println("The removed airport's name is \(removedValue).") } else { println("The airports dictionary does not contain a value for DUB.") } // prints "The removed airport's name is Dublin International."###字典遍历我们可以使用`for-in`循环来遍历某个字典中的键值对。每一个字典中的数据项都由`(key, value)`元组形式返回,并且我们可以使用临时常量或者变量来分解这些元组: for (airportCode, airportName) in airports { println("\(airportCode): \(airportName)") } // TYO: Tokyo // LHR: London Heathrow我们也可以通过访问它的keys或者values属性(都是可遍历集合)检索一个字典的键或者值: for airportCode in airports.keys { println("Airport code: \(airportCode)") } // Airport code: TYO // Airport code: LHR for airportName in airports.values { println("Airport name: \(airportName)") } // Airport name: Tokyo // Airport name: London Heathrow如果我们只是需要使用某个字典的键集合或者值集合来作为某个接受Array实例 API 的参数,可以直接使用keys或者values属性直接构造一个新数组: let airportCodes = Array(airports.keys) // airportCodes is ["TYO", "LHR"] let airportNames = Array(airports.values) // airportNames is ["Tokyo", "London Heathrow"]- 注意: Swift 的字典类型是无序集合类型。其中字典键,值,键值对在遍历的时候会重新排列,而且其中顺序是不固定的。###创建一个空字典我们可以像数组一样使用构造语法创建一个空字典: var namesOfIntegers = Dictionary() // namesOfIntegers 是一个空的 Dictionary这个例子创建了一个`Int`, `String`类型的空字典来储存英语对整数的命名。它的键是`Int`型,值是`String`型。
如果上下文已经提供了信息类型,我们可以使用空字典字面量来创建一个空字典,记作`[:]`(中括号中放一个冒号):
namesOfIntegers[16] = "sixteen"
// namesOfIntegers 现在包含一个键值对
namesOfIntegers = [:]
// namesOfIntegers 又成为了一个 Int, String类型的空字典
- 注意: 在后台,Swift 的数组和字典都是由泛型集合来实现的,想了解更多泛型和集合信息请参见泛型。
###集合的可变性
数组和字典都是在单个集合中存储可变值。如果我们创建一个数组或者字典并且把它分配成一个变量,这个集合将会是可变的。这意味着我们可以在创建之后添加更多或移除已存在的数据项来改变这个集合的大小。与此相反,如果我们把数组或字典分配成常量,那么它就是不可变的,它的大小不能被改变。
相反,如果你给常量赋值一个数组、集合或者字典,那它就是不可变的,大小和内容都不能修改。
Swift 数组的可变性行为同时影响了数组实例如何被分配和修改,想获取更多信息,请参见集合在赋值和复制中的行为。
- 注意: 在我们不需要改变数组大小的时候创建不可变数组是很好的习惯。如此 Swift 编译器可以优化我们创建的集合。