标签:
Swift提供了两种集合类型来存放多个值——数组(Array)和字典(Dictionary)。数组把相同类型的值存放在一个有序链表里。字典把相同类型的值存放在一个无序集合里,这些值可以通过唯一标识符(也就是键)来引用和查找。
在Swift里,数组和字典里所能存放的值的类型是明确的。这意味着你不能误把一个错误类型的值添加到数组或字典里,也意味着你可以明白无误地知道从数组
或字典里取得的值会是什么类型的。Swift集合是类型明确的,这保证了你的代码会清楚地知道它们所能处理的值的类型,并让你能在代码开发阶段就发现任何
输入错误。
注意: Swift的数组在赋值给常量、变量或者传值给函数、方法时,它的行为表现和其它类型并不一样。详情参见可变集合和集合类型的赋值和拷贝行为
数组在一个有序链表里存储了多个类型相同的值。同一个值可以在数组的不同位置出现多次。
Swift的数组对它们能存放的值的类型是明确的。这不同于Objective-C的NSArray类和NSMutableArray
类,Objective-C的数组能存储任何类型的对象,并且不提供关于这些对象自身的任何信息。在Swift里,任何一个特定的数组所能存储的值,其类
型总会被确定下来,或者通过显式的类型说明,或者通过类型推断,并且该类型不必是类类型。例如,如果你创建了一个Int型数组,你就不能把任何非Int型
的值插入这个数组。Swift数组是类型安全的,它总是知道它能存储什么值。
Swift数组的类型是Array<SomeType>,这里的SomeType是某种数组能够存放的类型。你也可以把数组类型简写为SomeType[]。尽管这两种形式功能上是一样的,我们更偏向于使用简写形式,本书里所有数组类型都是使用简写形式。
可以用一个数组字面量来初始化一个数组,简单地把一个或多个值放在一起就可以了。数组字面量的写法是一行用逗号隔开的值,并在行的两端用一对方括号包起来:
[value 1, value 2, value 3]
下面的例子创建了一个存放String类型值,名为shoppingList的数组:
根据String[],变量shoppingList被声明为“一个存放String值的数组”。因为这个数组指明了值类型为String,所以它只能存 放String类型的值。这里的shoppingList数组使用了一个数组字面量来初始化,该数组字面量含有两个String类型的元素("Eggs" 和"Milk")。
注意:数组shoppingList被声明为变量(用关键字var)而不是常量(用关键字let),是因为在下面的例子中会往这个购物清单里添加更多的元素。
在本例中,这个数组字面量只包含了两个String值。这和shoppingList变量定义中的类型一致(一个存放String值的数组),所以可以把这个数组字面量直接赋值给shoppingList进行初始化。
得益于Swift的类型推断,如果使用数组字面量来初始化一个数组,这个数组字面量里的值具有相同的类型,你可以不必明确写出这个数组的类型。上面初始化shoppingList的代码可以简写为:
因为数组字面量中的所有值具有相同的类型,Swift可以推断出shoppingList变量的类型就是String[]。
对数组的存取与修改可以通过数组的方法和属性来进行,或者使用数组的下标语法。
要知道数组中元素的数量,可以查看它的只读属性count:
使用Boolean型的isEmpty属性,可以快速检查count属性是否为0:
往数组的末尾添加一个元素,可以调用数组的append方法:
往数组末尾添加一个元素,也可以使用+=操作符:
你也可以使用+=操作符把一个类型相同的数组连接到数组后面:
从数组取得一个值可以使用下标语法。在数组名后面紧跟着的一对方括号中,传进去要取得的元素的索引值:
要注意数组第一个元素的索引值为0,而不是1。Swift的数组总是从0开始索引的。
你可以使用下标语法来改变给定索引的已存在的值:
你可以使用下标语法一次性改变指定范围的值,即使将要被替换掉的元素的数量和将要替换成的元素的数量不一样。下面的例子将"Chocolate Spread","Cheese"和 "Butter"替换为"Bananas"和"Apples"
注意: 不能使用下标语法添加新元素到数组末尾。如果试图使用超出数组范围的下标来取用或存放一个元素,会产生运行时错误。在使用一个索引值之前,应该把它跟数组 的count属性进行比较,以检测它是否有效。除非count是0(意味着这是个空数组),数组的最大有效索引总是count - 1,因为数组的索引是从0开始的。
插入一个元素到特定位置,可以调用数组的insert(atIndex:)方法:
本次调用insert函数,通过指明的下标0,向购物清单的开头添加了一个值为"Maple Syrup"的新元素。
类似地,你可以使用removeAtIndex方法从数组删除一个元素。该方法删掉指定索引上的元素,并返回这个被删掉的元素(如果你不需要返回值,可以忽略它):
当一个元素被删除时,数组中的不会留下任何空白无元素的地方。所以在索引0处的元素又变为"Six eggs"了:
如果想删除数组的最后一个元素,可以使用removeLast方法,而不必使用removeAtIndex方法,这样就可以避免还得调用数组的count属性。类似removeAtIndex方法,removeLast方法也返回被删除的元素:
你可以通过for-in循环来迭代访问整个数组的值。
如果要获得每个元素的索引及其对应的值,可以使用全局的enumerate方法来迭代使用这个数组。enumerate方法对每个元素都会返回一个由索引值及对应元素值组成的元组。你可以把元组中的成员转为变量或常量来使用:
要获得关于for-in循环的更多资料,请查看For Loops。
可以通过初始化语法创建一个特定类型的空数组,数组中不包含任何初始值:
要注意变量someInts会被推断为Int[]类型,因为它接收的是Int[]型初始化函数的返回值。
并且,如果上下文中已经提供了类型信息,例如方法的参数、已经定义类型的常量或变量,你就可以使用一个空的数组字面量来创建一个空的数组。空的数组字面量被写为[],就是一对不包括任何内容的方括号。
Swift的数组还提供了一个生成若干个重复元素组成的数组的初始化函数。把要添加到新数组里的元素数量(count)和一个合适的默认值(repeatedValue)传参给该初始化函数即可:
得益于Swift的类型推断,在使用这个初始化函数的时候,不必精确说明该数组的类型,因为这能从默认值中推断出来:
字典是一种存储多个类型相同的值的容器。每个值都和一个唯一的键相对应,这个键在字典里就是其对应值的唯一标识。跟数组不同,字典里的元素并没有特定的顺序。在“字典”中使用键来查询其对应值的方式,跟在“现实世界的字典”中使用单词查询单词定义差不多。
Swift的字典对它们能存放的键和值的类型是明确的。这不同于Objective-C的NSDictionary类和
NSMutableDictionary类,Objective-C的字典能存储任何类型的对象作为键或值,并且不提供关于这些对象自身的任何信息。在
Swift里,任何一个特定的字典键和值,其类型总会被确定下来,或者通过显式的类型说明,或者通过类型推断。
Swift的字典类型是Dictionary<KeyType, ValueType>,其中KeyType是字典中键的类型,ValueType是字典中值的类型。
对键类型KeyType的唯一限制是,它必须是可哈希的,也就是说,它必须能够提供一个方式让自己被唯一表示出来。Swift的所有基础类型(例如
String、Int、Double和Bool)默认都是可哈希的,这些类型都能够用作字典中的键。枚举成员中没有绑定值的值(参见枚举)默认也是可哈希的。
可以用一个字典字面量来初始化一个数组,其语法格式类似于之前看到的数组字面量。字典字面量是写一个具有单个或多个键值对字典的简便方法。
键值对是一个键和一个值的组合。在字典字面量中,每对键值对中的键和值使用冒号分开,键值对之间用逗号分开,用一对方括号将这些键值对包起来:
[key 1: value 1, key 2: value 2, key 3: value 3]
下面的例子创建了一个存储国际机场名字的字典,在这个字典中,键是三字母的国际航空运输协会码,值是机场的名字:
airports被定义为一个Dictionary<String, String>类型的字典,也就是“一个键的类型为String,值的类型也为String的字典”。
注意:字典airports被声明为变量(用关键字var)而不是常量(用关键字let),是因为在下面的例子中会往这个字典里添加更多的机场。
这里的字典airports使用了一个字典字面量来初始化,该字典字面量含有两个键值对,第一对的键为"TYO"、值为"Tokyo",第二对的键为"DUB"、值为"Dublin"。
在本例中,此数组字面量只包含了两个String: String键值对。这和airports变量定义中的类型一致(键的类型为String,值的类型也为String),所以可以把这个字典字面量直接赋值给airports进行初始化。
就像数组一样,如果使用具有相应类型的键和值的字典字面量来对字典进行初始化,你可以不必明确写出这个字典的类型。上面初始化airports的代码可以简写为:
因为这个字典字面量中的所有键具有相同的类型,所有值也具有相同的类型,Swift可以推断出airports变量的类型就是Dictionary<String, String>。
对字典的存取与修改可以通过字典的方法和属性来进行,或者使用字典的下标语法。就像数组一样,可以通过只读属性count获得Dictionary中元素的数量:
可以使用下标语法向字典中添加新的元素。以一个合适类型的新键作为下标索引,并且赋给它一个合适类型的值:
也可以使用下标语法来改动某个键对应的值:
在对特定键设置或更新值时,也可以使用updateValue(forKey:)函数来替代下标。就像上面例子中的下标语 法,updateValue(forKey:)函数在键不存在的时候就设置一个新值,在键存在的时候就更新该值。和下标语法不一样的 是,updateValue(forKey:)函数在更新一个值之后,会返回原来的老值。这让你能够检测是否发生了值的更新。
updateValue(forKey:)函数返回一个值的类型的可选值。例如一个值类型为String的字典,该函数返回值的类型为String?。如果更新前该键的值存在,函数返回值就是该键更新前的值,如果不存在,函数返回值就是nil:
你也可以使用下标语法从字典中对一个特定的键取值。因为可能会用到一个没有对应值存在的键,所以字典的下标语法返回的也是该字典值类型的可选值。如果字典中有该键对应的值,下标语法就返回该值,如果不存在,下标语法就返回nil:
也可以使用下标语法把一个键对应的值赋为nil来删除该键值对:
从字典中删除键值对也可以使用removeValueForKey函数。如果该键值对存在,该函数就返回本删掉的值,如果不存在,就返回nil:
你可以通过for-in循环来迭代访问整个字典的键值对。它会对字典中的每个元素都会返回一个(key, value)元组,你可以把元组中的成员转为变量或常量来使用:
要获得关于for-in循环的更多资料,请查看For Loops。
可以通过字典的keys属性和values属性,获得一个可以迭代访问的集合:
如果你需要将字典的所有键或者所有值放到一个Array对象里,可以直接使用字典的keys属性或者values属性:
注意: Swift的Dictionary类型不是一个有序集合,迭代访问字典的keys、values、键值对时候的顺序并无具体规定。
像数组一样,你可以使用初始化语法创建一个特定类型的空Dictionary:
这个例子创建了一个存储数字名称的空字典,键的类型是Int,值的类型是String。
如果上下文中已经提供了类型信息,可以使用空字典字面量[:]来创建一个空字典:
注意: 实际上,Swift的数组和字典类型是通过泛型集合实现的。要获得关于泛型类型和集合的更多资料,请查看Generics。
数组和字典都把多个值存放在一个集合里。如果你创建了一个数组或者字典,并且将之指定为变量,那么该集合就是可变的,这意味着在集合被创建后,可以通过增 加或删除元素来改变集合的容量大小。相反地,如果你指定一个数组或字典为常量,那么该数组或字典就是不可变的,其容量大小不能被改变。
对字典来说,不可变还意味着你不能改变字典里某个键的值。一个不可变的字典一旦被设置值后,它里面的内容就不能再改变。
但是,数组的不可变性跟字典略有不同。尽管你不能进行任何可能会改变数组大小的操作,但是你可以给数组中的某个索引设置一个新的值。这使得Swift的数组在大小固定的情况下能够达到最佳的性能。
Swift数组类型的可变性行为还会影响数组对象是如何被复制与修改的,详细信息可参见集合类型的复制与拷贝行为。
注意: 在任何不需要改变集合大小的地方,最好将集合定义为不可变的。这么做能让Swift的编译器优化该集合的性能。
标签:
原文地址:http://www.cnblogs.com/lianfu/p/4721693.html