1. 枚举的基本用法
- 使用 enum 关键词来定义 枚举;
enum Score {
case a, b, c, d
}
// 等价于
enum Score {
case a
case b
case c
case d
}
var score = Score.a
score = .b
print(score) // b
switch score {
case .a:
print("优秀")
case .b:
print("良好")
case .c:
print("及格")
case .d:
print("不及格")
}
2. 关联值
- 有时会将枚举的成员值跟 其他类型 的关联存在一起;
enum Score {
case point(Int)
case grade(Character)
}
var score = Score.point(90)
score = .grade("A")
switch score {
case let .point(s): // 获取关联值
print("score = \(s)")
case let .grade(g): // 获取关联值
print("core = \(g)")
}
enum Date {
case digit(year: Int, month: Int, day: Int)
case string(String)
}
var date = Date.digit(year: 2019, month: 6, day: 25)
date = .string("2019-06-25")
switch date {
case .digit(let year,let month, let day): // 获取关联值
print("year = \(year) , month = \(month), day = \(day)")
case .string(let dateStr): // 获取关联值
print(dateStr)
}
-
必要的时候,可以将 let 改为 var;
-
关联值实际使用场景;
enum Password {
case number(Int, Int, Int, Int)
case gesture(String)
}
var pw = Password.number(2, 4, 6, 8)
pw = .gesture("2468")
switch pw {
//case .number(let n1, let n2, let n3, let n4):
case let .number(n1, n2, n3, n4): // 或者这样写,两种写法等价
print("n1 = \(n1), n2 = \(n2), n3 = \(n3), n4 = \(n4)")
case let .gesture(g):
print("gesture = \(g)")
}
- 关联值的底层存储原理(类似 共用体):
- 1个字节存储成员值;
- N个字节存储关联值(N取占用内存最大的关联值),任何一个case的关联值都共用这N个字节;
- 所以整形关联值的枚举占用的内存大小为:(1 + n) * 8个字节, n 为最大关联数;
enum TestEnum {
case test1(Int, Int, Int)
case test2(Int, Int)
case test3(Int)
case test4(Bool)
case test5
}
// 1个字节存储成员值
// N个字节存储关联值(N取占用内存最大的关联值),任何一个case的关联值都共用这N个字节
// 共用体
// 小端:高高低低
// 01 00 00 00 00 00 00 00
// 02 00 00 00 00 00 00 00
// 03 00 00 00 00 00 00 00
// 00
// 00 00 00 00 00 00 00
var e = TestEnum.test1(1, 2, 3)
print(Mems.ptr(ofVal: &e))
// 04 00 00 00 00 00 00 00
// 05 00 00 00 00 00 00 00
// 00 00 00 00 00 00 00 00
// 01
// 00 00 00 00 00 00 00
e = .test2(4, 5)
print(Mems.memStr(ofVal: &e))
// 06 00 00 00 00 00 00 00
// 00 00 00 00 00 00 00 00
// 00 00 00 00 00 00 00 00
// 02
// 00 00 00 00 00 00 00
e = .test3(6)
// 01 00 00 00 00 00 00 00
// 00 00 00 00 00 00 00 00
// 00 00 00 00 00 00 00 00
// 03
// 00 00 00 00 00 00 00
e = .test4(true)
// 00 00 00 00 00 00 00 00
// 00 00 00 00 00 00 00 00
// 00 00 00 00 00 00 00 00
// 04
// 00 00 00 00 00 00 00
e = .test5
3. 原始值 (rawValue)
- 枚举成员可以使用相同类型的默认值预先关联,这个默认值叫做 原始值(rawValue);
- 原始值 不占用枚举变量内存;
enum Direction: String {
case east = "东"
case west = "西"
case south = "南"
case north = "北"
}
var direction = Direction.east
print(direction.rawValue) // 东
direction = .west
print(direction.rawValue) // 西
4. 隐式原始值
- 如果枚举的原始值类型为Int、String,swift将会自动设置原始值,如下:
enum Direction: String {
case east = "east"
case west = "west"
case south = "south"
case north = "north"
}
// 等价于
enum Direction: String {
case east, west, south, north
}
print(Direction.east.rawValue) // east
print(Direction.west.rawValue) // west
5. 递归枚举
- 使用 indirect 关键词,实现 enum 递归;
indirect enum Calculation {
case number(Int)
case sum(Calculation, Calculation)
}
// 也可以这样写
//enum Calculation {
// case number(Int)
// indirect case sum(Calculation, Calculation)
//}
let five = Calculation.number(5)
let four = Calculation.number(4)
let sum = Calculation.sum(five, four)
func calculation(_ cal: Calculation) -> Int {
switch cal {
case let .number(value):
return value
case let .sum(cal1, cal2):
return calculation(cal1) + calculation(cal2)
}
}
print("sum = \( calculation(sum) )") // 9
6. MemoryLayout
- 可以使用 MemoryLayout 来获取 数据类型 占用内存的大小;
enum Date {
case digit(year: Int, month: Int, day: Int)
case other
}
print( MemoryLayout<Date>.size ) // 实际占用的内存大小 25 = 3 * 8 + 1 三个整形(每个占用8个字节) + 1个字节(成员值类型 1个字节)
print( MemoryLayout<Date>.stride ) // 系统分配的内存 32 = 4 * 内存对齐参数
print( MemoryLayout<Date>.alignment ) // 内存对齐参数 8
let date = Date.digit(year: 2019, month: 6, day: 25)
print( MemoryLayout.size(ofValue: date) ) // 25
print( MemoryLayout.stride(ofValue: date) ) // 32
print( MemoryLayout.alignment(ofValue: date) ) // 8
let date = Date.other
print( MemoryLayout.size(ofValue: date) ) // 25
print( MemoryLayout.stride(ofValue: date) ) // 32
print( MemoryLayout.alignment(ofValue: date) ) // 8
源代码demo
网友评论