上一篇:集合类型
当前篇:集基础大杂烩
下一篇:函数
元组
元组把多个值组合成一个复合值,元组中的值可以是任何类型,我们用元组来模拟一下人这种类型,我们把人的姓名、昵称、性别、籍贯、年龄等信息组合成一个复合类型
let jiangming = ("姜明", "小明", "男", "重庆", 24)
let myName = jiangming.0
let myHometown = jiangming.3
我们可以通过元素的位置下标来访问元组中的元素,这样使用起来意思不明,我们可以给元组的每一个元素起一个名字
let jiangming = (name: "姜明", nick: "小明", gender: "男", hometown: "重庆", age: 24)
let myName = jiangming.name
let myHometown = jiangming.hometown
如果我们自己定义元组的类型,不使用自动类型推断
let jiangming: (name: String, nick: String, gender: String, hometown: String, age: Int) = ("姜明", "小明", "男", "重庆", 24)
let myName = jiangming.name
let myHometown = jiangming.hometown
这样的类型定义写起来太麻烦,而且如果要在其他地方使用这个元组类型,又要写一遍很长的类型声明,我们可以给这样的类型起一个专用名字,于是就有了类型别名
类型别名
类型别名 typealias 就是给某个类型起一个别名,这样你就可以用自己喜欢或者更好理解的方式去使用类型名称,但是要注意在你的项目中类型名称包括别名是不能重复的,否则会编译失败
我们给上面的元组起一个别名
typealias Person = (name: String, nick: String, gender: String, hometown: String, age: Int)
//现在 Person 就代表我们自己定义的元组类型了
let jiangming: Person = ("姜明", "小明", "男", "重庆", 24)
let myName = jiangming.name
let myHometown = jiangming.hometown
我们可以给任意类型起别名
typealias 整数 = Int
let a: 整数 = 0
可选类型
上一节课我们提到了可选类型,任何类型都可以声明为可选的类型,方式就是 类型名? ,表示它的值可能是空的,也可能有值。比如,我可以用字符串来创建一个整数,但是像 “abc” 这样的字符串是不能转换成整数的,所以用字符串来创建整数得到的结果一定是一个 Int?
let aString = "abc"
let possibleNumber = Int(aString)
//possibleNumber 被推断为 Int? 类型,并且它的值为 nil
let aString = "123"
let possibleNumber = Int(aString)
//possibleNumber 被推断为 Int? 类型,并且它的值为 123
强制解析
当我们使用可选值的时候,可以在其名字后面加上 ! 来转换成普通值,这叫 强制解析 ,在进行强制解析的时候一定要确保可选值不为空,对一个空值进行强制解析会造成程序崩溃
let aString = "123"
let possibleNumber = Int(aString)
if possibleNumber != nil {
//如果判断为有值,则用!进行强制解析
print(possibleNumber!)
} else {
print("This is not a string that can be resolved as a number")
}
强制解析实际上就是把可选类型的值强制转换成非可选类型的值,所以需要确保其是有值的
let aString = "123"
let possibleNumber = Int(aString)
if possibleNumber != nil {
let definiteNumber: Int = possibleNumber!
print(definiteNumber)
} else {
print("This is not a string that can be resolved as a number")
}
隐式解析
可选类型还有另一种定义方法,那就是 类型名! ,仅仅是问号和感叹号的区别,这两种方式定义的类型都是可选类型,但是用叹号定义的可选类型已经包含了解析的语义,我们不用在使用的过程中进行强制解析,只需要判断是否为空就行了
let possibleNumber: Int!
possibleNumber = Int("123")
if possibleNumber != nil {
print(possibleNumber)
}
隐式解析可选类型只做了解,在遇到的时候知道这个概念就行了,实际上隐式解析的区别就是,只需要做非空判断,不需要强制解析
空值替换
let aString = "abc"
let possibleNumber = Int(aString)
let replacedNumber: Int = possibleNumber ?? 0
双问号 ?? 的意思是如果有值,就取其值,如果没有值,就取后面给定的默认值,如果默认值是普通类型,那自然得到的结果就是一个非可选类型了
可选绑定
试想一下这样的情况,有一个可选值,而后面有很多行代码都要用到这个值,你就需要在每个地方都用一次感叹号来强制解析,就像下面这样
let aString = "123"
let possibleNumber = Int(aString)
if possibleNumber != nil {
print(possibleNumber!)
print(possibleNumber!)
print(possibleNumber!)
print(possibleNumber!)
print(possibleNumber!)
print(possibleNumber!)
} else {
print("This is not a string that can be resolved as a number")
}
这样写比较难看,而且强制解析多多少少也是需要计算的,我们可以像下面这样只解析一次
let aString = "123"
let possibleNumber = Int(aString)
if possibleNumber != nil {
let definiteNumber: Int = possibleNumber!
print(definiteNumber)
print(definiteNumber)
print(definiteNumber)
print(definiteNumber)
print(definiteNumber)
print(definiteNumber)
} else {
print("This is not a string that can be resolved as a number")
}
Swift 为我们提供了一种更优雅的写法叫 可选绑定 ,可选绑定其实就是把上面的判断以及强制解析两个过程合成一句话
let aString = "123"
let possibleNumber = Int(aString)
if let definiteNumber = possibleNumber {
print(definiteNumber)
print(definiteNumber)
print(definiteNumber)
print(definiteNumber)
print(definiteNumber)
print(definiteNumber)
} else {
print("This is not a string that can be resolved as a number")
}
可选绑定可以有多个语句,用逗号隔开
let string1 = "123"
let possibleNumber1 = Int(string1)
let string2 = "abc"
let possibleNumber2 = Int(string2)
if let definiteNumber1 = possibleNumber1, let definiteNumber2 = possibleNumber2 {
//需要两个条件都成立才算成功
print(definiteNumber1)
print(definiteNumber2)
} else {
print("There is at least one string that can be resolved as a number")
}
枚举
枚举是编程语言中一个非常常用的概念,比如说 方向 这个类型,它总共就四种取值,而且四种取值只能取其一(咱先不考虑西北东北这种方向,假设就四种方向),这种类型我们就用枚举来表示
enum Position {
case north
case south
case east
case west
}
let myWayForward = Position.north
enum 表示定义一个枚举类型,Position 是我们自己定义的枚举类型的名字,大括号括起来的就是我们自己定义的枚举类型的具体定义,我们给 Position 类型定义了四个值:north,south,east,west ,实际上,这个类型是我们自己定义的第一个类型,今后很多的类型都会是我们自己定义的
我们用了一个字面量来初始化一个枚举值 myWayForward ,方式就是 枚举类型名.其中的某个值 ,现在 myWayForward 就是一个 Position 类型的值,它的值等于 north ,当一个枚举的类型已知的时候,我们可以把枚举类型名称省略掉,只留下一个小点就行了
enum Position {
case north
case south
case east
case west
}
let myWayForward: Position = .north
枚举判断
我们可以用 if 来判断枚举值
enum Position {
case north
case south
case east
case west
}
let myWayForward: Position = .north
if myWayForward == .north {
print("一路向北")
} else if myWayForward == .south {
print("一直往南方开")
} else if myWayForward == .east {
print("东方之珠")
} else {
print("一路向西")
}
而最常用的是用 switch-case 语句来处理枚举值
enum Position {
case north
case south
case east
case west
}
var myWayForward: Position = .north
myWayForward = .south
switch myWayForward {
case .north:
print("一路向北")
case .south:
print("一直往南方开")
case .east:
print("东方之珠")
case .west:
print("一路向西")
//当所有可能的结果都被列举了,default 就不需要了
}
枚举原始值
枚举中的值可以关联一个原始值,可以是整数,浮点数,字符串或者字符
enum Position: Int {
case north = 0
case south = 1
case east = 2
case west = 3
}
var myWayForward: Position = .north
myWayForward = .south
print(myWayForward.rawValue)
//通过 rawValue 属性获取枚举值的关联值
如果我们定义的枚举值需要跟其他应用通信,需要是关联整数的枚举值,因为通信需要标准统一,不能我用字符串别人用整数,如果仅仅是本地使用,而且不需要关联任何原值值,可以不关联
在通信过程中,我们通过网络获取到的枚举数据一般都是一个整数值,需要使用整数值来创建关联整数类型的枚举
enum Position: Int {
case north = 0
case south = 1
case east = 2
case west = 3
}
var myWayForward: Position? = Position(rawValue: 0)
myWayForward = .south
print(myWayForward!.rawValue)
这种方式创建的枚举值是可选类型枚举值,因为我们给定的原始值不一定会有对应的枚举值,代码中我没有做非空判断是因为我知道 0 对应了 north
当我们用整数作为枚举的关联值,可以不必为每一个枚举值都指定关联值,Swift 会为我们自动推断,我们只需要指定第一个枚举值的原始值,后面的枚举值的原始值单调递增1
enum Position: Int {
case north //0,0 开头的情况可以省略不写
case south //1
case east //2
case west //3
}
enum Position: Int {
case north = 1
case south //2
case east //3
case west //4
}
用字符串作为关联值有时候会非常方便,请看下面两种代码
enum Mood {
case happy
case anger
case sad
case surprised
}
let myMood = Mood.happy
switch myMood {
case .happy:
print("")
case .anger:
print("Get out of my face!")
case .sad:
print("Leave me alone please!")
case .surprised:
print("Hahahahahaha!!")
}
enum Mood: String {
case happy = ""
case anger = "Get out of my face!"
case sad = "Leave me alone please!"
case surprised = "Hahahahahaha!"
}
let myMood = Mood.happy
print(myMood.rawValue)
//直接就输出了关联的字符串,不需要做判断
上一篇:集合类型
当前篇:集基础大杂烩
下一篇:函数