本想把枚举、结构体和类都一起放到上一篇《Swift 学习记:基础知识》之中,但是当把一些功能,如属性和方法都剥离到另一篇笔记之后,发现独立成一篇更方便理解,内容也更简约。
故。
枚举
枚举(enumeration)能让你定义明确类型的实例。
定义
使用 enum
关键字定义枚举:
enum TestEnum {
case left
case right
case center
}
// 创建枚举实例
var testEnum: TestEnum = TestEnum.left // 显式声明类型
var testEnum = TestEnum.left // 或者使用类型推断创建
testEnum = .right // 重新赋值时可省略
**注:**第一次创建枚举的实例时必须指定枚举名
原始值
当需要存储或传输枚举时,可使用原始值(raw value)。
// 在枚举名后面加上希望的原始值类型
enum TestEnum: Int {
case left
case right
case center
}
// 使用 .rawValue 查看原始值
print(TestEnum.right.rawValue) // 返回 1
**注:**整数原始值的默认值,从 0 开始;
指定原始值
enum TestEnum: Int {
case left = 10
case right // 如果不省略原始值,将根据上一位数字递增,这里为11
case center = 30
}
// 依据原始值,获得枚举值
let enumVar = TestEnum(rawValue: 30) // 返回 center
字符串原始值
// 原始值类型为 String
enum testEnum: String {
case left = "zuo"
case right // 省略原始值将使用原值,这里为 right
case center = "zhong"
}
关联值
关联值(Associated Values)可以让你把数据附在枚举实例上,不同成员可以有不同类型的关联值。
enum ShapeEnum {
// 关联值类型为 Double
case square(side: Double)
case rectangle(width: Double, height: Double)
// 使用 switch 语句检查和计算
func area() -> Double {
switch self {
case .square(let side):
return side * side
case .rectangle(let width, let height):
return width * height
}
}
}
// 关联值
var shareShape = ShapeEnum.square(side: 10)
shareShape.area() // 将返回 100
注:
- 关联值,即把参数附加到方法上;
- 不是所有的枚举都需要关联值,两者可以混合;
递归枚举
递归枚举(Recursive Enumerations)是拥有另一个枚举作为枚举成员关联值的枚举,在声明枚举成员之前需要使用 indirect
关键字来明确它是递归的.
enum Calc {
case num(Int)
indirect case add(Int, Calc)
}
// 也可以在枚举之前标记,而不是针对单个成员
indirect enum Calc {
case num(Int)
case add(Int, Calc)
}
结构体和类
结构体(Structure)和类(Classes)是构建应用这座大厦的支柱。
定义
关键字 struct
定义结构体,class
关键字定义类:
// 定义结构体并初始化
struct TestStruct {
var width = 0
var height = 0
}
// 定义类并初始化
class TestClass {
var width = 0
var height = 0
}
// 创建实例
let testClass = TestClass()
// 使用点语法赋予类新值
testClass.height = 7
// 使用点语法访问属性
print(testClass.height) // 返回 7
枚举、结构体和类的异同与选择
从功能上看三者之间的区别:
- 相同点,均支持
- 属性:存储值;
- 方法:提供功能;
- 下标:使用下标语法访问值;
- 初始化:初始化状态;
- 扩展:增加默认实现功能;
- 协议:提供特定类型的标准功能;
- 类独有
- 继承:可以让一个类继承另一个类的特征;
- 类型转换:运行检查和解释一个类实例的类型;
- 反初始化:允许一个类实例释放任何被其所分配的资源;
- 自动引用计数:允许对一个类实例进行多次引用;
但是结构体和类除了上面列出的功能之外,另外还有一个主要区别:枚举和结构体是值类型,而类是引用类型
,值类型在产生操作时会产生一个副本,而引用类型,则是创建引用。或者说,值类型是拷贝(复制)操作,相互独立,不同步更改;而引用类型是替身(快捷方式),指向的是源文件,会同步更改。
struct TestStruct {
var say = "Hello"
}
class TestClass {
var say = "Hello"
}
var testStruct = TestStruct()
var str = testStruct
str.say = "Hi"
print(testStruct.sayi // 值类型,不会同步更改,所以返回 Hello
var testClass = TestClass()
var cla = testClass
cla.say = "Hi"
print(testClass.say) // 引用类型,同步更改,返回 Hi
选结构体还是类
从之前的简单示例可以看出,结构体和类的语法相似,功能相似,所以如何在两者之间选择:
- 选结构体(值类型)
- 需要传值;
- 不需要继承;
- 数据比较直观;
- 明确知道数据需要被拷贝;
- 选类(引用类型)
- 其它情况
除非绝对清楚需要引用类型的好处,否则用结构体比较合适,值类型更容易理解,也无需担心实例发生变化。
**注:**枚举、结构体和类均使用大驼峰式命名法
,方法和属性则使用小大驼峰式命名法
信息
版本
- Xcode 10.1
- Swift 4.2.1