枚举的基本用法
关联值(Associated Values)
关联值举例
原始值(Raw Values)
注:原始值不占用枚举变量的内存
隐式原始值(Implicitly Assigned Raw Values)
递归枚举(Recursive Enumeration)
MemoryLayout
MemoryLayout<Int>.size // 实际用到的空间大小
MemoryLayout<Int>.stride // 分配占用的空间大小
MemoryLayout<Int>.alignment // 对齐参数
MemoryLayout.size(ofValue: age)
MemoryLayout.stride(ofValue: age)
MemoryLayout.alignment(ofValue: age)
enum Password {
case number(Int, Int, Int, Int) // 32个字节
case other // 1个字节->其实不是other占1个字节 是枚举类型变量占1个字节
}
var pwd = Password.number(1, 5, 4, 4) // 33个字节
// 枚举类型变量会占用1个字节 不论枚举变量类型是Int还是String 都不会根据定义类型来计算字节大小
enum Season {
case spring, summer, autumn, winter // 1个字节
}
// other的1不是说other占一个字节 这一个1节其实用来区分number还是other
/// 关联值跟原始值的区别
/// 1、关联类型的枚举,其实是会存储对应的关联类型的值的,关联类型占用多少个字节就影响枚举的内存
/// 关联值会占用枚举变量的内存,会根据外界传值类型计算大小
/// 2、原始值不允许你自定义,也不会根据枚举类型计算内存大小
/// 原始值不会占用枚举变量的内存,只会占用1个字节,用来标记枚举类型
思考下面枚举变量的内存布局
func testEnum() {
enum TestEnum {
case test1(Int, Int, Int)
case test2(Int, Int)
case test3(Int)
case test4(Bool)
case test5
}
// 小端:高高低低
// 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
}
枚举 - 关联值
1个字节存储成员值
N个字节存储关联值(N取占用内存最大的关联值),任何一个case的关联值都共用这N个字节
共用体枚举 - 原始值
原始值不占用枚举内存
如果只有一个case的话 不会占用内存
如果超过1个case 会有1个字节去存储区分具体是哪个case
窥探内存
窥探内存细节的小工具: https://github.com/CoderMJLee/Mems