# Swift字典字面量我們可以使用字典字面量來構(gòu)造字典,它們和我們剛才介紹過的數(shù)組字面量擁有相似語法。一個(gè)字典字面量是一個(gè)定義擁有一個(gè)或者多個(gè)鍵值對(duì)的字典集合的簡單語句撼唾。一個(gè)鍵值對(duì)是一個(gè)key和一個(gè)value的結(jié)合體馏慨。在字典字面量中,每一個(gè)鍵值對(duì)的鍵和值都由冒號(hào)分割棒拂。這些鍵值對(duì)構(gòu)成一個(gè)列表伞梯,其中這些鍵值對(duì)由方括號(hào)包含并且由逗號(hào)分割:? ? [key 1: value 1, key 2: value 2, key 3: value 3]下面的例子創(chuàng)建了一個(gè)存儲(chǔ)國際機(jī)場(chǎng)名稱的字典。在這個(gè)字典中鍵是三個(gè)字母的國際航空運(yùn)輸相關(guān)代碼帚屉,值是機(jī)場(chǎng)名稱:? ? var airports: [String:String] = ["TYO": "Tokyo", "DUB": "Dublin"]`airports`字典被定義為一種 `[String: String]`,它意味著這個(gè)字典的鍵和值都是`String`類型谜诫。- 注意: `airports`字典被聲明為變量(用`var`關(guān)鍵字)而不是常量(`let`關(guān)鍵字)因?yàn)楹髞砀嗟臋C(jī)場(chǎng)信息會(huì)被添加到這個(gè)示例字典中。`airports`字典使用字典字面量初始化攻旦,包含兩個(gè)鍵值對(duì)喻旷。第一對(duì)的鍵是`TYO`,值是`Tokyo`牢屋。第二對(duì)的鍵是`DUB`且预,值是`Dublin`。這個(gè)字典語句包含了兩個(gè)`String: String`類型的鍵值對(duì)烙无。它們對(duì)應(yīng)airports變量聲明的類型(一個(gè)只有`String`鍵和`String`值的字典)所以這個(gè)字典字面量是構(gòu)造兩個(gè)初始數(shù)據(jù)項(xiàng)的`airport`字典锋谐。和數(shù)組一樣,如果我們使用字面量構(gòu)造字典就不用把類型定義清楚截酷。`airports`的也可以用這種方法簡短定義:? ? var airports = ["TYO": "Tokyo", "DUB": "Dublin"]因?yàn)檫@個(gè)語句中所有的鍵和值都分別是相同的數(shù)據(jù)類型涮拗,Swift 可以推斷出`Dictionary`是`airports`字典的正確類型。###讀取和修改字典我們可以通過字典的方法和屬性來讀取和修改字典合搅,或者使用下標(biāo)語法多搀。和數(shù)組一樣,我們可以通過字典的只讀屬性count來獲取某個(gè)字典的數(shù)據(jù)項(xiàng)數(shù)量:? ? println("The dictionary of airports contains \(airports.count) items.")? ? // 打印 "The dictionary of airports contains 2 items."(這個(gè)字典有兩個(gè)數(shù)據(jù)項(xiàng))可以使用布爾屬性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.(這個(gè)字典不為空)"我們也可以在字典中使用下標(biāo)語法來添加新的數(shù)據(jù)項(xiàng)康铭。可以使用一個(gè)合適類型的 key 作為下標(biāo)索引赌髓,并且分配新的合適類型的值:? ? airports["LHR"] = "London"? ? // airports 字典現(xiàn)在有三個(gè)數(shù)據(jù)項(xiàng)我們也可以使用下標(biāo)語法來改變特定鍵對(duì)應(yīng)的值:? ? airports["LHR"] = "London Heathrow"? ? // "LHR"對(duì)應(yīng)的值 被改為 "London Heathrow作為另一種下標(biāo)方法从藤,字典的updateValue(forKey:)方法可以設(shè)置或者更新特定鍵對(duì)應(yīng)的值。就像上面所示的示例锁蠕,updateValue(forKey:)方法在這個(gè)鍵不存在對(duì)應(yīng)值的時(shí)候設(shè)置值或者在存在時(shí)更新已存在的值夷野。和上面的下標(biāo)方法不一樣,這個(gè)方法返回更新值之前的原值荣倾。這樣方便我們檢查更新是否成功悯搔。`updateValue(forKey:)`函數(shù)會(huì)返回包含一個(gè)字典值類型的可選值。舉例來說:對(duì)于存儲(chǔ)String值的字典舌仍,這個(gè)函數(shù)會(huì)返回一個(gè)String?或者“可選 String”類型的值妒貌。如果值存在通危,則這個(gè)可選值值等于被替換的值,否則將會(huì)是`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)我們也可以使用下標(biāo)語法來在字典中檢索特定鍵對(duì)應(yīng)的值菊碟。由于使用一個(gè)沒有值的鍵這種情況是有可能發(fā)生的,可選類型返回這個(gè)鍵存在的相關(guān)值在刺,否則就返回`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."(機(jī)場(chǎng)的名字是都柏林國際)我們還可以使用下標(biāo)語法來通過給某個(gè)鍵的對(duì)應(yīng)值賦值為nil來從字典里移除一個(gè)鍵值對(duì):? ? airports["APL"] = "Apple Internation"? ? // "Apple Internation"不是真的 APL機(jī)場(chǎng), 刪除它? ? airports["APL"] = nil? ? // APL現(xiàn)在被移除了另外逆害,removeValueForKey方法也可以用來在字典中移除鍵值對(duì)。這個(gè)方法在鍵值對(duì)存在的情況下會(huì)移除該鍵值對(duì)并且返回被移除的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`循環(huán)來遍歷某個(gè)字典中的鍵值對(duì)蚣驼。每一個(gè)字典中的數(shù)據(jù)項(xiàng)都由`(key, value)`元組形式返回魄幕,并且我們可以使用臨時(shí)常量或者變量來分解這些元組:? ? for (airportCode, airportName) in airports {? ? ? ? println("\(airportCode): \(airportName)")? ? }? ? // TYO: Tokyo? ? // LHR: London Heathrow我們也可以通過訪問它的keys或者values屬性(都是可遍歷集合)檢索一個(gè)字典的鍵或者值:? ? 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如果我們只是需要使用某個(gè)字典的鍵集合或者值集合來作為某個(gè)接受Array實(shí)例 API 的參數(shù),可以直接使用keys或者values屬性直接構(gòu)造一個(gè)新數(shù)組:? ? let airportCodes = Array(airports.keys)? ? // airportCodes is ["TYO", "LHR"]? ? let airportNames = Array(airports.values)? ? // airportNames is ["Tokyo", "London Heathrow"]- 注意: Swift 的字典類型是無序集合類型隙姿。其中字典鍵梅垄,值,鍵值對(duì)在遍歷的時(shí)候會(huì)重新排列输玷,而且其中順序是不固定的队丝。###創(chuàng)建一個(gè)空字典我們可以像數(shù)組一樣使用構(gòu)造語法創(chuàng)建一個(gè)空字典:? ? var namesOfIntegers = Dictionary()? ? // namesOfIntegers 是一個(gè)空的 Dictionary這個(gè)例子創(chuàng)建了一個(gè)`Int`, `String`類型的空字典來儲(chǔ)存英語對(duì)整數(shù)的命名。它的鍵是`Int`型欲鹏,值是`String`型机久。
如果上下文已經(jīng)提供了信息類型,我們可以使用空字典字面量來創(chuàng)建一個(gè)空字典赔嚎,記作`[:]`(中括號(hào)中放一個(gè)冒號(hào)):
namesOfIntegers[16] = "sixteen"
// namesOfIntegers 現(xiàn)在包含一個(gè)鍵值對(duì)
namesOfIntegers = [:]
// namesOfIntegers 又成為了一個(gè) Int, String類型的空字典
- 注意: 在后臺(tái)膘盖,Swift 的數(shù)組和字典都是由泛型集合來實(shí)現(xiàn)的,想了解更多泛型和集合信息請(qǐng)參見泛型尤误。
###集合的可變性
數(shù)組和字典都是在單個(gè)集合中存儲(chǔ)可變值侠畔。如果我們創(chuàng)建一個(gè)數(shù)組或者字典并且把它分配成一個(gè)變量,這個(gè)集合將會(huì)是可變的损晤。這意味著我們可以在創(chuàng)建之后添加更多或移除已存在的數(shù)據(jù)項(xiàng)來改變這個(gè)集合的大小软棺。與此相反,如果我們把數(shù)組或字典分配成常量尤勋,那么它就是不可變的喘落,它的大小不能被改變。
相反最冰,如果你給常量賦值一個(gè)數(shù)組瘦棋、集合或者字典,那它就是不可變的暖哨,大小和內(nèi)容都不能修改赌朋。
Swift 數(shù)組的可變性行為同時(shí)影響了數(shù)組實(shí)例如何被分配和修改,想獲取更多信息,請(qǐng)參見集合在賦值和復(fù)制中的行為箕慧。
- 注意: 在我們不需要改變數(shù)組大小的時(shí)候創(chuàng)建不可變數(shù)組是很好的習(xí)慣服球。如此 Swift 編譯器可以優(yōu)化我們創(chuàng)建的集合。