由蘋果官網翻譯得來
fork自https://github.com/letsswift/The-Swift-Programming-Language-in-Chinese
由https://github.com/TyrantDante/The-Swift-Programming-Language-in-Chinese 完善和檢查
Swift 提供三種集合類型來存儲集合,數組,sets(集合)和字典。數組是一個同類型的序列化列表集合。sets是特定類型的無序集合。字典是一個能夠使用類似于鍵的唯一標識符來獲取值的非序列化集合。

在Swift中,數組,sets(集合)和字典里的鍵和值都必須是明確的某個特定類型。這意味這數組和字典不會插入一個錯誤的類型的值,以致于出錯。這也意味著當你在數組和字典中取回數值的時候能夠確定它的類型。
Swift 使用確定的集合類型可以保證代碼工作是不會出錯,和讓你在開發(fā)階段就能更早的捕獲錯誤。
swift中數組,set和字典被是實現成常用的集合,更多請關注Generics
可變集合
如果你創(chuàng)建了一個數組,set或者字典,并且申明他為變量,那么該集合就是可變的。這就意味著你可以通過添加、刪除或者改變他的item來改變這個集合。如果你申明了數組,set或者字典為常量,那么他就沒辦法修改。他的內容和大小都沒法修改。
如果集合不需要修改,盡量申明成常量。這樣編譯器會優(yōu)化你的集合。
數組
數組是儲存同類型多數值的序列化列表。同樣的值可以在數組的不同位置出現多次。
swift中的Array 是橋接自Foundation的NSArray。更多請關注Using Swift with Cocoa and Objective-C (Swift 2.2).
數組的簡略語法
定義數組的完整寫法是Array<SomeType>,其中SomeType是你想要包含的類型。你也可以使用類似于SomeType[]這樣的簡略語法。雖然這兩種方法在功能上是相同的。但是我們更推薦后者,而且它會一直貫穿于本書。
創(chuàng)建一個空的數組
可以使用構造語句來創(chuàng)建某些類型的數組
var someInts = [Int]()
print("someInts is of type [Int] with \(someInts.count) items.")
// prints "someInts is of type [Int] with 0 items"
注意someInts在初始化時就被定義成int的數組,是無法添加其他類型的。
如果數組已經被制定了值類型,你就可以通過‘[]’空的中括號創(chuàng)建一個空的數組。
someInts.append(3)
// someInts now contains 1 value of type Int
someInts = []
// someInts is now an empty array,but is still of type [Int]
創(chuàng)建一個默認數值的數組
swift中數組也可以創(chuàng)建并且出實話一個帶有默認個數和相同的默認值的數組。你傳遞給初始化函數數組個數(count)和一個合適類型的默認值(repeatedValue)
var threeDoubles = [Double](count:3,repeatedValue:0.0)
// threeDoubles is type [Double],and equals [0.0,0.0,0.0]
創(chuàng)建一個數組由其他兩個數組相加
最后,你可以使用(+)操作符就能創(chuàng)建一個新的數組,把兩個存在的數組添加進來
這個新的數組類型從你添加的兩個數組中推斷出來
var anotherThreeDoubles = [Double](count:3,repeatedValue:2.5)
// anotherThreeDoubles is of type [Double],and equals [2.5,2.5,2.5]
var sixDoubles = threeDouble + anotherThreeDoubles
// sixDoubles is inferred as [Double],and equals [0.0,0.0,0.0,2.5,2.5,2.5]
使用數組實量創(chuàng)建數組
你可以用一個數組實量(Array Literals)來初始化一個數組,它是用簡略寫法來創(chuàng)建一個包含一個或多個的值的數組。一個數組實量(Array Literals)是由它包含的值,“,”分隔符 已經包括以上內容的中括號對“[]”組成:
[value 1, value 2, value 3]
下面的例子是創(chuàng)建一個叫shoppinglist,儲存字符串(String)類型的數組。
var shoppingList:[String] = ["Eggs", "Milk"]
// 使用兩個初始化參數來初始化shoppingList
shoppinglist變量被定義為字符串(String)類型的數組,寫作[String]。因為這個數組被確定為字符串類型(String),所以它只能儲存字符串(String)類型的值。在這里,我們用兩個字符串類型的值(”Eggs” and “Milk”)和數組實量(Array Literals)的寫法來初始化shoppingList數組。
注意
shoppingList數組是被定義為一個變量(使用var 標識符)而不是常量(使用let 標識符),所以在下面的例子可以直接添加元素。
在這個例子中,數組實量(Array Literals)只包含兩個字符串類型的值,這符合了shoppingList變量的定義(只能包含字符串(String)類型的數組),所以被分配的數組實量(Array Literals)被允許用兩個字符串類型的值來初始化。
得益于Swift的類型推斷,當你用相同類型的值來初始化時,你可以不寫明類型。初始化shoppingList可以用下面這個方法來代替。
var shoppingList = ["Eggs", “Milk"]
因為數組實量(Array Literals)中所有的值都是同類型的,所以Swift能夠推斷shoppingList的類型為字符串數組([String])。
讀取和修改數組
你可以通過方法和屬性,或者下標來讀取和修改數組。
通過只讀屬性count來讀取數組的項數;
print("The shopping list contains \(shoppingList.count) items.")
// 打印出 "The shopping list contains 2 items.”
通過一個返回布爾類型的isEmpty屬性檢查數組的項數是否為0
if shoppingList.isEmpty {
print("The shopping list is empty.")
} else {
print("The shopping list is not empty.")
}
// 打印出 "The shopping list is not empty."
在數組末尾增加一項可以通過append方法
shoppingList.append("Flour")
// shoppingList 現在包含3項
同理,也可以用(+=)操作符來把一個元素添加到數組末尾
shoppingList += "Baking Powder"
// shoppingList 現在包含4項
你也可以用(+=)操作符來把一個數組添加到另一個數組的末尾
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// shoppingList 現在包含7個元素
從數組中取出一個值可以使用下標語法。如果你知道一個元素的索引值,你可以數組名后面的中括號中填寫索引值來獲取這個元素
var firstItem = shoppingList[0]
// firstItem 等于 “Eggs"
注意,數組的第一個元素的索引值為0,不為1,Swift的數組的索引總是從0開始;
你可以使用下標語法通過索引修改已經存在的值。
shoppingList[0] = "Six eggs"
//列表中的第一個值等于"Six eggs" 而不等于 “Eggs"
你可以使用下標語法一次性改變一系列的值,盡管修改的區(qū)域遠遠大于要修改的值。在下面的例子中, 把 “Chocolate Spread”, “Cheese”和”Butter”替換為”Bananas”和”Apples”:
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList 現在包含6個元素
注意,你不能使用下標語法在數組中添加一個元素,如果你嘗試使用下標語法來獲取或者設置一個元素,你將得到一個運行時的錯誤。盡管如此,你可以通過count屬性驗證索引是否正確再使用它。除非count等于0(也就是說數組是空的),最大的索引都是count-1,因為數組的索引從0開始計算。
在一個特定的索引位置插入一個值,可以使用insert(atIndex:)方法
shoppingList.insert("Maple Syrup", atIndex: 0)
// shoppingList 現在包含7個元素
// "Maple Syrup" 在數組的第一位
這里調用insert方法指明在shoppingList的索引為0的位置中插入一個新元素 “Maple Syrup”
同理,你可以調用removeAtIndex方法移除特定的元素。這個方法移除特定索引位置的元素并返回這個被移除的元素(盡管你可能并不關心這個返回值)。
let mapleSyrup = shoppingList.removeAtIndex(0)
// 索引位置為0的元素被移除
// shoppingList 現在包含6個元素, 不包括 Maple Syrup
// mapleSyrup 常量等于被移除的 "Maple Syrup" 字符串
當元素被移除的,數組空缺的位置將會被填補,所以現在索引位置為0的元素再一次等于”Six eggs”:
firstItem = shoppingList[0]
// firstItem 現在等于 "Six eggs”
如果你想從數組中移除最后一個元素,使用removeLast方法比removeAtIndex更方便,因為后者需要通過count屬性計算數組的長度。和removeAtIndex方法一樣,removeLast會返回被移除的元素。
let apples = shoppingList.removeLast()
//元素的最后一個元素被移除
// shoppingList 現在包含5個元素,不包括 cheese
// apples 常量 現在等于被移除的 "Apples" string
遍歷數組
可以使用for-in循環(huán)來遍歷數組中的值
for item in shoppingList {
print(item)
}
// Six eggs
// Milk
// Flour
// Baking Powder
// Bananas
如果既需要每個元素的值,又需要每個元素的索引值,使用enumerate函數代替會更方便,enumerate函數對于每一個元素都會返回一個包含元素的索引和值的元組(tuple)。你可以在遍歷部分分解元素并儲存在臨時變量或者常量中。
for (index, value) in enumerate(shoppingList) {
print("Item \(index + 1): \(value)")
}
// Item 1: Six eggs
// Item 2: Milk
// Item 3: Flour
// Item 4: Baking Powder
// Item 5: Bananas
如需更多for-in 循環(huán)信息, 參見 For Loops.
Sets
一個集合存儲了一串無序的相同類型的數據。如果對順序沒有要求,或者只是用一次的時候,可以使用set來替代數組。
swift set類型橋接自Foundation中的NSSet類
參見[Using Swift with Cocoa and Objective-C] (https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/index.html#//apple_ref/doc/uid/TP40014216).
set類型中的哈希值
儲存進一個集合的類型必須是可以哈?;?。該類行必須提供一個方法來計算它本身的哈希值。哈希值是一個int值。所有相同的對象的哈希值是一樣的。如果a == b 的返回值和 a.hashValue == b.hashValue 的返回值是一樣的,
所有的swift基本類型(String,Int,Double,Bool)默認是可以哈?;?。而且可以用類設置值類型或者字典鍵類型。沒有關聯值得枚舉值也是默認可以哈?;摹?/p>
你可用使用自定義類型來設置值類型或字典類型,自定義類型需要從swift標準庫遵守哈希化協議。遵守哈希化協議的類型必須提供一個叫做hashValue的方法(返回類型為Int)。hashValue的值在不同的程序或相同的程序中返回不要求相同。
因為哈希化協議是可變的。遵守協議的類型必須實現運算符(== or ‘is equal’)。Equatable協議要求必須實現“==”成一個等價關系。見下面的例子
a == a (自反性)
a == b 相當于 b == a(對稱性)
a == b && b == c 相當于 a == c (傳遞性)
查看相關protocol資料,詳見Protocols
集合類型語法
集合類型的語法是Set<Element>,Element是允許存入集合中的類型。
更數組不同的是,集合沒有簡便方法。
創(chuàng)建和初始化一個空集合
你可以通過某些類型的構造方法來創(chuàng)建一個空的集合
var letters = Set<Character>()
print("letters is if type Set<Character> with \(letters.count) items")
//Prints "letters is of type Set<Character> with 0 items."
letters變量的類型是由Set<Character>的構造器獲得。
如果上下文已經提供了類型信息,就可以通過設置一個空的數組實例來創(chuàng)建一個空的集合
letters.insert("a")
// letters now contains 1 value of type Character
letters = []
// letters is now an empty set, but is still of type Set<Character>
通過數組實例創(chuàng)建創(chuàng)建集合
你也可以通過一個數組實例創(chuàng)建集合。這是一個簡寫的方式寫入一或多個值。
下面的例子,favoriteGenres 存儲多個string 值
var favoriteGenres:Set<String> = ["Rock","Classical","Hip hop"]
//favoriteGenres has been initialized with three initial items
favoriteGenres變量被定義成一個字符串的集合,寫成Set<String>.因其指定了值類型是字符創(chuàng),所以他只能儲存字符串的值,這里favoriteGenres被初始化并賦值成(“Rock”,“Classical” ,“Hip hop”).
集合類型不能從數組常量中推斷出來,所以集合類型中Set關鍵字必須加上。結合swfit的特性,用包含值得數組實例初始化的話,你不需要寫集合包含的類型。favoriteGenres可以被簡寫成這樣:
var favoriteGenres:Set = ["Rock","Classical","Hip hop"]
因為數組實例中的所有值都是一個類型,swift可以推斷出一個正確的類型給favoriteGenres變量,為Set<String>
訪問和修改一個集合
可以通過集合的方法和屬性來訪問和改變他
獲取一個set的item數量,使用它的只讀屬性count
print("I have \(favoriteGenres.count) favorite music genres.")
// Prints "I have 3 favorite music genres."
使用布爾類型的isEmpty 快捷的檢查他的count是不是 0
if favoriteGenres.isEmpty {
print("As far as music goes, I'm not picky.")
} else {
print("I have particular music preferences.")
}
// Prints "I have particular music preferences."
用 insert(_:)方法添加一個item
favoriteGenres.insert("Jazz")
// favoriteGenres nw contains 4 items
通過 remove(_:)方法來刪除一個item,如果集合擁有這個item,返回被remove的值,如果沒有返回nil,當然可以用 removeAll方法移除所有的items
if let removedGenre = favoriteGenres.remove("Rock") {
print("\(removedGenre)? I'm over it.")
} else {
print("I never much cared for that.")
}
// Prints "Rock? I'm over it."
通過contains(_:)方法來檢查集合是否包含該item
if favoriteGenres.contains("Funk") {
print("I get up on the good foot.")
} else {
print("It's too funky in here.")
}
// Prints "It's too funky in here."
遍歷集合
你可以使用for-in來遍歷集合的所有值
for genre in favoriteGenres {
print("\(genre)")
}
// Classical
// Jazz
// Hip hop
執(zhí)行集合操作
您可以有效地執(zhí)行基本設置操作,如結合兩套在一起,確定哪些值兩組的共同點,或決定是否兩套包含所有,或沒有一個相同的值。
基本的集合操作
下面的說明描述了兩個集合(a,b)各種集合操作的結果所代表的陰影區(qū)域。

intersect(_:)方法:返回兩個集合都擁有的元素的集合,
exclusiverOr(_:)方法:返回兩個集合去除都擁有的元素后的所有的元素的集合
union(_:)方法:返回兩個集合的所有元素的集合
-
subtract(_:)方法:返回去除目標集合中另一個集合所包含的元素所得的集合
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]oddDigits.union(evenDigits).sort()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersect(evenDigits).sort()
// []
oddDigits.subtract(singleDigitPrimeNumbers).sort()
// [1, 9]
oddDigits.exclusiveOr(singleDigitPrimeNumbers).sort()
// [1, 2, 9]
集合之間的項目關系和相等
下面的插圖描述了三個集合a,b和c和重疊區(qū)域代表元素集之間共享。設置a是b的超集,因為包含了所有元素b。相反地,b是a的一個子集,因為所有元素b也包含于a。b,c是不相交的,因為他們沒有共同之處。

"=="(is equal)方法:判斷兩個集合是否擁有相同的元素,相同返回true,反之false
isSubsetOf(_:)方法:判斷目標集合是是否為參數集合的子集,是則返回true,反之false
isSupersetOf(_:)方法:判斷目標集合是否為參數集合的超集,是則返回true,反之false
isStrictSubsetOf(_:)和isStrictSupersetOf(_:)方法:判斷目標是否是子集和超集,但是必須是兩個集合不相等,滿足以上條件返回true,反之false
-
isDisjointWith(_:)方法:判斷兩個集合有無相同元素,有相同元素則返回false,反之true。
let houseAnimals: Set = ["??", "??"]
let farmAnimals: Set = ["??", "??", "??", "??", "??"]
let cityAnimals: Set = ["??", "??"]houseAnimals.isSubsetOf(farmAnimals)
// true
farmAnimals.isSupersetOf(houseAnimals)
// true
farmAnimals.isDisjointWith(cityAnimals)
// true
字典
字典是儲存同一類型多個值的容器。每一個值都對應這一個唯一的鍵(Key),就像是字典內的每一個值都有一個標識符。和數組內的元素是有區(qū)別的,字典內的元素是沒有特殊的序列的。當你需要根據標識符來查找批量的值時,就可以使用字典,和在真實世界的字典中尋找某個字的解釋相似。
Swift字典儲存一個特定類型的鍵和值,與Objective-C的NSDictionary 和NSMutableDictionary不同,因為它們是使用各種的對象來作為它們的鍵和值,而且并不提供任何有關對象的具體信息。在Swift中,對于一個特定的字典,它所能儲存的鍵和值的類型都是確定的,無論是明確聲明的類型還是隱式推斷的類型。
Swift的字典寫法是Dictionary<KeyType,ValueType>,KeyType是你想要儲存的鍵的類型,ValueType是你想要儲存的值的類型。
唯一的限制就是KeyType必須是可哈希的(hashable)——就是提供一個形式讓它們自身是獨立識別的。Swift的所有基礎類型(例如字符串(String),整形(Int),雙精度(Double)和布爾(Bool))在默認是可哈希的(hashable),和這些類型都常常被當作字典的鍵。沒有協助值(associated values)的枚舉成員(具體描述在 Enumerations)默認也是可哈希的(hashable)。
創(chuàng)建一個空字典
和字典一樣,你可以使用確定類型的語法創(chuàng)建一個空的字典。
var namesOfIntegers = [Int:String]()
// namesOfIntegers 是一個空的 [Int: String] 類型的字典
這個例子創(chuàng)建一個Int,String類型的字典來儲存可讀性較好的整數值。它的鍵是Int類型,它的值是String類型。
如果 上下文(context )中已經提供類型信息,可用一個字典實量(Dictionary Literal)創(chuàng)建一個空的字典,寫作[;](由一對[]包含一個冒號:)
namesOfIntegers[16] = "sixteen"
// namesOfIntegers現在包含1 個鍵值對
namesOfIntegers = [:]
// namesOfIntegers 是一個類型為Int, String的空字典。
字典實量(Dictionary Literals)
你可以直接用一個字典實量(Dictionary Literals)初始化一個字典。和前面定義一個數組實量(Array Literals)的語法一樣。字典實量(Dictionary Literals)就是使用簡略寫法直接寫一個或者多個對應的鍵和值對來定義一個字典。
一個鍵值對是一個鍵和值的組合。在字典實量(Dictionary Literals)里面,每一個鍵值對總是用一個冒號把鍵和值分割。鍵值對的寫法就想是一個列表,使用逗號分割,并被一對中括號[]包含著:
[key 1: value 1, key 2: value 2, key 3: value 3]
在下面的例子,將會創(chuàng)建一個字典來儲存國際機場的名字。在這個字典里面,鍵是三個字的國際航空運送協會代碼,以及它的值是機場的名稱:
var airport :[String: String] = ["TYO": "Tokyo", "DUB": “Dublin"]
airport字典被定義為一個類型為[String:String],這意味這,這個字典的鍵類型是字符串String,和它的值的類型也是String。
注意
airport字典是被定義為一個變量(使用var 標識符)而不是常量(使用let 標識符),所以在下面的例子可以直接添加元素。
airport字典使用一個包含兩個鍵值對的字典實量(Dictionary Literals)來初始化。第一對有一個叫“TYO”的鍵和一個叫“Tokyo”的值,第二對有一個叫“DUB”的鍵和一個叫“Dublin”的值。
這個字典實量(Dictionary Literals)包含兩個字符串(String):字符串對。這符合airport變量定義的類型(一個字典只包括字符串(String)鍵和字符串(String)值),所以在分配字典實量(Dictionary Literals)的時候被允許作為airport字典的兩個初始化元素。
和數組一樣,如果你初始化一個字典的時候使用相同的類型,你可以不指明字典的類型。
airport初始化可以用下面這個簡略寫法來代替:
var airports = ["TYO": "Tokyo", "DUB": “Dublin”]
因為所有的鍵在字面上都是相同的類型,同樣,所有的值也是同樣的類型,所以Swift可以推斷為[String:String]是airports字典的正確類型。
讀取和修改字典
你可以通過屬性,方法或者下標來讀取和修改字典。和數組一樣,你使用只讀的count屬性來檢查字典(Dictionary)包含多少個元素。
print("The dictionary of airports contains \(airports.count) items.")
// 打印 "The dictionary of airports contains 2 items."
你可以使用下標語法給一個字典添加一個元素。使用合適類型作為新的鍵,并分配給它一個合適類型的值
airports["LHR"] = "London"
// airports dictionary 現在有 3 items
你也可以使用下標語法去改變一個特定鍵所關聯的值。
airports["LHR"] = "London Heathrow"
//"LHR" 的值已經被改變?yōu)?"London Heathrow"
同樣, 使用字典的updateValue(forKey:) 方法去設置或者更新一個特定鍵的值 . 和上面的下標例子一樣, updateValue(forKey:) 方法如果鍵不存在則會設置它的值,如果鍵存在則會更新它的值, 和下標不一樣是, updateValue(forKey:) 方法如果更新時,會返回原來舊的值,意味著你可以使用這個來判斷數據是否發(fā)生了更新。
updateValue(forKey:) 方法返回一個和字典的值相同類型的可選值. 例如,如果字典的值的類型時String,則會返回String? 或者叫“可選String“,這個可選值包含一個如果值發(fā)生更新的舊值和如果值不存在的nil值。
if let oldValue = airports.updateValue("Dublin International", forKey: "DUB") {
print("The old value for DUB was \(oldValue).")
}
// prints "The old value for DUB was Dublin."
你也可以使用下標語法通過特定的鍵去讀取一個值。因為如果他的值不存在的時候,字典的下標語法會返回一個字典的值的類型的可選值。如果字典中的鍵包含對應的值,這字典下標語法會返回這個鍵所對應的值,否則返回nil
if let airportName = airports["DUB"] {
print("The name of the airport is \(airportName).")
} else {
print("That airport is not in the airports dictionary.")
}
// prints "The name of the airport is Dublin International."
你可以使用下標語法把他的值分配為nil,來移除這個鍵值對。
airports["APL"] = "Apple International"
// "Apple International" 不是APL的真實機場,所以刪除它
airports["APL"] = nil
// APL已經從字典中被移除
同樣,從一個字典中移除一個鍵值對可以使用removeValueForKey方法,這個方法如果存在鍵所對應的值,則移除一個鍵值對,并返回被移除的值,否則返回nil。
if let removedValue = airports.removeValueForKey("DUB") {
print("The removed airport's name is \(removedValue).")
} else {
print("The airports dictionary does not contain a value for DUB.")
}
// prints "The removed airport's name is Dublin International."
遍歷字典
你可以使用一個for-in循環(huán)來遍歷字典的鍵值對。字典中的每一個元素都會返回一個元祖(tuple),你可以在循環(huán)部分分解這個元祖,并用臨時變量或者常量來儲存它。
for (airportCode, airportName) in airports {
print("\(airportCode): \(airportName)")
}
// TYO: Tokyo
// LHR: London Heathrow
更多有關for-in 循環(huán)的信息, 參見 For Loops.
你也可以讀取字典的keys屬性或者values屬性來遍歷這個字典的鍵或值的集合。
for airportCode in airports.keys {
print("Airport code: \(airportCode)")
}
// Airport code: TYO
// Airport code: LHR
for airportName in airports.values {
print("Airport name: \(airportName)")
}
// Airport name: Tokyo
// Airport name: London Heathrow
如果你需要一個接口來創(chuàng)建一個字典的鍵或者值的數組實例,你可以使用keys或者values屬性來初始化一個數組。
let airportCodes = Array(airports.keys)
// airportCodes is ["TYO", "LHR"]
let airportNames = Array(airports.values)
// airportNames is ["Tokyo", "London Heathrow"]
注意
Swift中的字典類型是非序列化集合,序列化取回鍵,值,或者鍵值對的順序是不明確的。
可變集合類型
數組和字典都是在一個集合中一起儲存多個變量.如果你創(chuàng)建一個數組或者字典,再包含一個變量,創(chuàng)建的這個變量被稱為可變的(mutable) 這意味這,你可以在創(chuàng)建之后增加更多的元素來改變這個集合的長度,或者移除已經包含的。相反的, 如果你把一個數組或者字典定義為常量,則這個數組或者字典不是可變的,他們包含的項數并不能被改變。
在字典中,不可變也意味著你不能替換已經存在的鍵的值。一個不可變字典,一旦被設置就不能改變。
數組的不可變有一點點的不同。然而,你仍然不能做任何改變項數的操作。但是你可以重新設置一個已經存在的索引,這使得當Swift的數組的長度確定時,能更好地優(yōu)化數組的性能。
擁有可變行為的數組也影響著數組實例的分配和修改,更多內容參見Assignment and Copy Behavior for Collection Types.
注意
在一個集合的項數不需要被改變時,創(chuàng)建不可變集合是非常好的嘗試。這樣的話Swift編譯器就能充分利用你所創(chuàng)造的集合的性能。