标签:swift array dictionary generic nsarray
一.引子:
在2014年10月TIOBE编程语言排行榜中,Swift位居第18位,从2014WWDC发布会首次公布至今不到半年时间,swift一直受到编程人员的追捧,其热衷程度并不亚于当红巨星Taylor Swift。相信在不远的将来,swift能够平稳发展,并逐步取代Objective-C。
二.swift的集合类型
下面回归主题。作为一名iOS开发者,我们已经非常熟悉诸如NSArray,NSDictionary,NSSet等常见集合类型,以及它们的可变同类NSMutableArray,NSMutableDictionary,NSMutableSet。而swift则为我们提供了原生的Array和Dictionary集合类型,遗憾的是,目前还没有提供Set这样的集合类型(预计将来可能会添加进去)。与Objective-C不同的是,swift不存在对应的mutable类型,原因是一个集合类型是否可变是通过修饰符var和let决定的,因此,如果一个集合类型的变量是let修饰的,则这个集合类型是不可变的。如果一个集合类型的变量是var修饰的,则这个集合类型是可变的。例如:
var mutableArray = Array<Int>() mutableArray.append(1) let immutableArray = Array<String>() immutableArray.append("item") // 编译时错误
三.范型集合
Objective-C的集合类型对集合里的元素只有一个要求,那就是它必须是一个OC对象(很多时候我们想要往里面添加基本数据类型时,都要用NSNumber封装一下才能放到集合里去)。而swift则不同,swift宣称自己是类型安全的,因为swift的特性里包含现代语言里都会有的范型(generic)。因此我们在调用集合类型的初始化方法时,都要注明这个集合类型的元素数据类型。比如:
var intArray = Array<Int>() intArray.append(2014) intArray.append("2014") // 编译时错误 var creditDictionary = Dictionary<String,Int>() creditDictionary.updateValue(88888, forKey: "Benson")
在上面的例子中,声明了一个整形数组和一个KeyType为String,ValueType为Int的字典。整形数组里只能存放整形元素,如果放入字符串元素,编译器就会报错(值得注意的是,如果放入浮点类型或者布尔类型,编译器会自动将其转换为整形,比如3.14转换成3,true转换为1)。有了范型,就可以确保类型安全,而不用再进行类型判断和强制类型转换等麻烦操作。
(数组的元素类型没有任何限制,但是字典对KeyType设定了类型限制(Type Constraints),它规定KeyType必须实现Hashable协议,该协议规定遵循类必须提供gettable的hashValue属性。值得庆幸的是,String,Int,Double,Bool等常用类型都实现了该协议,一般情况下够用了。)
四.简写形式
对于集合类型的初始化,大多数情况下都不采用上面例子中的写法,而是采用更加简洁的形式。
var shorthandArray = [Int]() // var intArray = Array<Int>() var shorthandDictionary = [String:Int]() // var creditDictionary = Dictionary<String,Int>()
shorthandArray = [] // empty array shorthandDictionary = [:] // empty dictionary
五.集合类型的遍历
集合类型最常用的操作莫过于遍历集合。下面分别针对数组和字典进行遍历:
var carArray = [String]() carArray.append("Mercedes-Benz") carArray.append("Toyota") carArray.append("Porsche") for car in carArray { println(car) }
输出结果:
(这水印。。)
如果在循环过程中需要得到索引值,可以使用swift标准库中的全局函数enumerate:
for (index,value) in enumerate(carArray) { println("index\(index):\(value)") }
index0:Mercedes-Benz index1:Toyota index2:Porsche
var animalLegs = [String:Int]() animalLegs.updateValue(4, forKey: "deer") animalLegs.updateValue(8, forKey: "crab") animalLegs.updateValue(2, forKey: "kangaroo") for (animal,legs) in animalLegs { println("\(animal) has \(legs)leg(s)") }
六.使用下标(subscript)
数组Array和字典Dictionary可以使用下标的形式进行添加,删除和替换等操作,比如:
var carArray = [String]() carArray.append("Mercedes-Benz") carArray.append("Toyota") carArray.append("Porsche") carArray[0] = "BMW" // 奔驰被替换成宝马了 [ replace 操作] var animalLegs = [String:Int]() animalLegs.updateValue(4, forKey: "deer") animalLegs.updateValue(8, forKey: "crab") animalLegs.updateValue(2, forKey: "kangaroo") animalLegs["sheep"] = 4 // 添加一个元素 animalLegs["deer"] = nil // 删除一个元素 animalLegs["crab"] = 6 // 替换元素的值 if let legs = animalLegs["kangaroo"] { println("kangaroo has \(legs)legs") } else { println("not defined") }
针对数组的操作,下标好像只能进行替换,不能添加元素,也不能删除元素(如果将某个元素设置为nil,需将数组的元素类型设置为optional)。
针对字典的操作则比较齐全,可以进行CRUD。需要特别注意的是,通过下标获取字典某个key的值的时候,返回的类型是ValueType?(即optional的值类型),可以采用optional binding或者if和!搭配使用提取该值,因为字典中可能不存在该值,从而可能为nil。
七.集合类型的简便初始化
可能是说漏了,但也是最重要的一点,就是如何利用数组和字典的字面量(literal)对变量进行赋值。
var countryArray = ["China","Japan","Russia","India","Canada"] var festivalDic = ["National's Day":"10-01","Christmas Day":"12-25","New Year":"01-01"]
最后需要强调一点的是,Array和Dictionary跟OC的NSArray和NSDictionary不同,Array和Dictionary是值类型(value type),不是引用类型,因此,Array和Dictionary传值一般都是copy,其原始值不会受到影响:(更具体一点,Array和Dictionary都是struct类型,String也不例外。)
var original = [1,2,3] var steal = original steal.append(4) original.count // 3 steal.count // 4
标签:swift array dictionary generic nsarray
原文地址:http://blog.csdn.net/tounaobun/article/details/39830457