Swift中的集合类型

一.引子:

在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")    // 编译时错误

如果不知道修饰符let和var的区别,可以这样简单理解,let修饰的变量是常量,一旦赋值后就不能再改变。而var修饰的变量的值可以动态改变。

三.范型集合

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>()

如上所示,对于数组类型来说,只需在中括号中声明数组的类型,接着再跟一对小括号即可(小括号里也可带有初始化的参数,比如[Int](count:3,repeatedValue:0) ),对于字典类型来说,只需再中括号中声明key和value的类型,并以冒号分隔即可,接着再跟一对小括号,同理,小括号里也可带有相应初始化方法的参数。另外一种情况是,如果已知某个变量为集合类型,那么再次赋值时可以采用更简单的形式:

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)
}

上面的例子中采用for in 循环,循环打印数组中每个元素。(println是swift内置全局函数,类似于java的System.out.println()方法。另外可以看到for循环中无需用小括号包围)

输出结果:

(这水印。。)

如果在循环过程中需要得到索引值,可以使用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)")
}

和遍历数组类似,只不过遍历的每一项是一个元组(tuple),该元组包含两个元素,一个是key,一个是value。

六.使用下标(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"]

数组的字面量一般形式是[value,value,value...],字典的一般形式是[key:value,key:value,key:value,...]。数组和字典的数据类型是通过类型推导(type inferrence)得出来的,对于数组来说,由于数组里的元素都是String,因此countryArray的数据类型是[String],同理,festivalDic的数据类型是[String:String]。

最后需要强调一点的是,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
时间: 10-05

Swift中的集合类型的相关文章

Swift 学习- 05 -- 集合类型

// 集合类型 // swift 提供 Arrays , Sets 和 Dictionaries 三种基本的集合类型用来存储数据 , 数组(Arrays) 是有序数据的集, 集合(Sets)是无序无重复数据的集, 字典(Dictionaries) 是无序的键值对的集 // swift 语言中的 Arrays, Sets 和 Dictionaries 中存储的数据值类型必须明确, 这意味着我们不能把不正确的数据类型插入其中, 同事这也说明我们完全可以取回值的类型非常自信 // 集合的可变性 //

IOS开发语言Swift入门连载---集合类型

IOS开发语言Swift入门连载-集合类型 Swift语言提供经典的数组和字典两种集合类型来存储集合数据.数组用来按顺序存储相同类型的数据.字典虽然无序存储相同类型数据值但是需要由独有的标识符引用和寻址(就是键值对). Swift语言里的数组和字典中存储的数据值类型必须明确. 这意味着我们不能把不正确的数据类型插入其中. 同时这也说明我们完全可以对获取出的值类型非常自信. Swift 对显式类型集合的使用确保了我们的代码对工作所需要的类型非常清楚,也让我们在开发中可以早早地找到任何的类型不匹配错

浅谈swift中的函数类型和闭包

在讲swift的函数类型之前,我们先回忆一下我们以前学的定义一个swift的函数 func add(a: Int,b: Int) -> Int { return a + b } 好了, 我们开始我们函数类型的讲解 上面这个函数的类型是(Int ,Int)->Int 使用函数类型 我们都知道, 在swift中 , 函数类型就像其他数据类型一样,也就意味着我们可以给一个函数的常量或者是变量赋值 var f2: (Int,Int)-> Int = add f2(2,3) //结果为5 好了,接

Swift中的Void类型与空元祖表达式

可能有不少Swift开发者会忽略这么一个细节:在Swift中,Void类型其实是一个别名类型,而其真正的类型为(),即一个空元祖(empty tuple)! 这种语言特性给Swift带来了一些比较方便的表达方式.当()作为函数返回类型时,它作为一个类型:当它作为一个表达式时,则表示一个空元祖.这样,我们在返回类型为()(或Void)的Swift函数中可以,最后返回一个不干任何事的空元祖,这在三目表达式中尤为有用.请看以下代码: var sss = 0 func MyFunc() -> () {

Swift中的Optional类型 (可选类型)与强制解包 ? !

我们在swift的开发中会经常遇见?和! ,理解这两个符号深层次的内容对我们的开发是相当有利的: 目前网上对swift3.0的教程还相当的少,如果去搜索会发现早期的说法,在定义变量的时候,swift是不会给变量赋值初始值的,所以当你声明一个字符串变量的时候,var string:String   就会被系统报错,但是目前的swift版本却不报错了. 但是你要给一个字符串赋值未nil的时候,var string:String = nil 就一定是错误的   因为nil并不是一个字符串类型,而实际上

Swift——(六)Swift中的值类型

在Swift中,结构体和枚举类型为值类型(Structures and Enumerations),在Stack Overflow上有这样一个问题:结构体中的可变属性只有在使用mutating关键字之后才能被内置的方法修改(如果是不可变属性肯定不可以修改了,这就不用纠结了,不过在Swift中,还有一个例外,那就是构造器Initialization,对于结构体和类的常量实例属性可以在构造器中进行设置,这感觉有点违背常量属性的含义,仔细想想也可以理解,因为实例化的时候,最后调用的是构造器,所以在构造

swift 初见-5集合类型

// Playground - noun: a place where people can play import UIKit var str = "Hello, playground" // swift的集合类型只有数组和字典 // 数组中只能存储相同类型的数据(可以是基本类型,也可以是类对象) // 申明方法 [String] Array<String> // 一旦隐是声明后,他的类型就确定了,不能在存储其他类型的数据了 var array=["a"

[Swift]Day03:集合类型

集合类型 数组 重复值的初始化 除了普通的初始化方法,我们可以通过 init(count: Int, repeatedValue: T) 来初始化一个数组并填充上重复的值: // [0.0,0.0,0.0] var threeDoubles = [Double](count:3,repeatedValue:0.0) 带索引值的遍历 我们可以用 for in 遍历数组,如果想要 index 的话,可以用 enumerate<Seq : SequenceType>(base: Seq) : let

Swift 笔记 (四) —— 集合类型

集合类型 Swift 提供了两种集合类型, Array, Dictionary Array与Dictionary 都须要存同样类型的数据  //实际測试的时候发现能够混杂类型,以下有样例 Array 是有序的, Dictionary 是无序的 Dictionary须要一组无唯一的索引用于查找,也就是key Array 原型: Array<SomeType>, SomeType指的是要放在Array里的数据类型 var myArray: String[] = ["var1",