从上图看出不管是实际使用还是分配的内存都是1一个字节,但预设值是Int类型的,一个Int在64位系统是8个字节,一个字节是存储不下,实际原始值类型的枚举不管什么类型都是1个字节,枚举本身并不会存储实际的值
直接从内存看会清楚点,Swift里面枚举是没法直接看到内存的,得获取内存地址自己去找,但实际上Swift也没提供方式看内存地址https://github.com/CoderMJLee/Mems借助这个工具吧
原始值的内存结构
代码如图,打上断点,获取输出的内存地址
查看内存结构
因为第一个断点下标就是0所以看不出来有什么区别,然后走到第二个断点也就是west执行完了还没执行east
可以看到变成了01也就是第二个下标
再走变成了2,可以说明在有原始值的枚举里面存储结构就是只存下标,那个实际值可能存储在常量区,在枚举自定义的RawValue函数直接返回(等我有空看看源码,但可以确定不在枚举的内存里面)
关联值的内存结构
简单编写一个关联值的枚举,可以看出实际内存是33,分配了40个字节,那是因为内存对齐是8
和刚才一样三个断点
8个字节对应一个Int16进制的64就是100,另外这个是小端,单个的内存读取是从右往左读的,所以这里是0x0000000000000064也就是100,正好对应第一个值,C8就对应了200,64和08也是,08后面还有一个字节,是0,在这个看的不明显,继续往下走
会发现之前那个位置的00变成了01,而开头的16个字节存了41,42,43这三个十六进制数对应的是65 66 67,对应的ASCII码表的值就是ABC,而E3是个符号,又位于16位,是字符串的起始标记
再往下走,是字符的c,刚好对应43没毛病,但标记位置变成了02
可以得出结论了,关联枚举会存值,只会存最大的那个(case+1)的内存,然后考虑到内存对齐,会分配一个对齐的内存,然后读取根据下标来,比如上面的枚举,先读取最后的下标,然后把前面的内存分4*8,前4个读取Int,如果下标1,则读取前面16个字节,如果下标是2也读取前面16个字节(Character也是16字节),以此类推
所以枚举在switch里面为啥能用也就好理解了,因为不管是哪个枚举都是有下标的,但如果枚举就一个,就不会生成下标了,但就一个case的枚举并没有什么实际意义