枚舉的基本用法
關(guān)聯(lián)值(Associated Values)
關(guān)聯(lián)值舉例
原始值(Raw Values)
注:原始值不占用枚舉變量的內(nèi)存
隱式原始值(Implicitly Assigned Raw Values)
遞歸枚舉(Recursive Enumeration)
MemoryLayout
MemoryLayout<Int>.size // 實(shí)際用到的空間大小
MemoryLayout<Int>.stride // 分配占用的空間大小
MemoryLayout<Int>.alignment // 對(duì)齊參數(shù)
MemoryLayout.size(ofValue: age)
MemoryLayout.stride(ofValue: age)
MemoryLayout.alignment(ofValue: age)
enum Password {
case number(Int, Int, Int, Int) // 32個(gè)字節(jié)
case other // 1個(gè)字節(jié)->其實(shí)不是other占1個(gè)字節(jié) 是枚舉類(lèi)型變量占1個(gè)字節(jié)
}
var pwd = Password.number(1, 5, 4, 4) // 33個(gè)字節(jié)
// 枚舉類(lèi)型變量會(huì)占用1個(gè)字節(jié) 不論枚舉變量類(lèi)型是Int還是String 都不會(huì)根據(jù)定義類(lèi)型來(lái)計(jì)算字節(jié)大小
enum Season {
case spring, summer, autumn, winter // 1個(gè)字節(jié)
}
// other的1不是說(shuō)other占一個(gè)字節(jié) 這一個(gè)1節(jié)其實(shí)用來(lái)區(qū)分number還是other
/// 關(guān)聯(lián)值跟原始值的區(qū)別
/// 1挎峦、關(guān)聯(lián)類(lèi)型的枚舉,其實(shí)是會(huì)存儲(chǔ)對(duì)應(yīng)的關(guān)聯(lián)類(lèi)型的值的澜倦,關(guān)聯(lián)類(lèi)型占用多少個(gè)字節(jié)就影響枚舉的內(nèi)存
/// 關(guān)聯(lián)值會(huì)占用枚舉變量的內(nèi)存庄蹋,會(huì)根據(jù)外界傳值類(lèi)型計(jì)算大小
/// 2、原始值不允許你自定義卓箫,也不會(huì)根據(jù)枚舉類(lèi)型計(jì)算內(nèi)存大小
/// 原始值不會(huì)占用枚舉變量的內(nèi)存载矿,只會(huì)占用1個(gè)字節(jié),用來(lái)標(biāo)記枚舉類(lèi)型
思考下面枚舉變量的內(nèi)存布局
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
}
枚舉 - 關(guān)聯(lián)值
1個(gè)字節(jié)存儲(chǔ)成員值
N個(gè)字節(jié)存儲(chǔ)關(guān)聯(lián)值(N取占用內(nèi)存最大的關(guān)聯(lián)值),任何一個(gè)case的關(guān)聯(lián)值都共用這N個(gè)字節(jié)
共用體枚舉 - 原始值
原始值不占用枚舉內(nèi)存
如果只有一個(gè)case的話(huà) 不會(huì)占用內(nèi)存
如果超過(guò)1個(gè)case 會(huì)有1個(gè)字節(jié)去存儲(chǔ)區(qū)分具體是哪個(gè)case
窺探內(nèi)存
窺探內(nèi)存細(xì)節(jié)的小工具: https://github.com/CoderMJLee/Mems