Swift中枚举的内存布局

2020-11-14  本文已影响0人  lieon

枚举

枚举的基本用法

enum Direction {
    case north
    case south
    case east
    case west
}
let dir: Direction = .north

关联值(Associated Values)

enum Score {
    case points(Int)
    case grade(String)
}

let score: Score = .points(3)

原始值(Raw Values)

enum Grade: String {
    case perfect = "A"
    case great = "B"
    case good = "C"
    case bad = "D"
}

隐式原始值(Implicitly Assigned Raw Values)

enum Direction: String {
    case north = "north"
    case south = "south"
    case east = "east"
    case west = "west"
}

/// 等价于
enum Direction {
    case north
    case south
    case east
    case west
}

递归枚举(Recursive Enumeration)

indirect enum ArithExpr {
    case number(Int)
    case sum(ArithExpr, ArithExpr)
}
enum ArithExpr {
    case number(Int)
    indirect case sum(ArithExpr, ArithExpr)
}

MemoryLayout

基础枚举内存大小为

- 系统分配1个字节
- 实际用到1个字节
- 按1个字节对接

enum TestEnum1 {
    case test1
    case test2
    case test3
}

enum TestEnum2: Int {
    case test1
    case test2
    case test3
}

var test = TestEnum1.test3
print(Mems.ptr(ofVal: &test))
print(Mems.size(ofVal: &test))
let stride = MemoryLayout<TestEnum1>.stride // 1
let size = MemoryLayout<TestEnum1>.size // 1
let alignment = MemoryLayout<TestEnum1>.alignment // 1

关联值枚举内存大小为(TestEnum3为例)

- 分配的内存大小为32个字节
- 实际用到的字节为25个字节
- 以8个字节对齐
// 01 00 00 00 00 00 00 00
// 02 00 00 00 00 00 00 00
// 03 00 00 00 00 00 00 00
// 01
// 分配了32个字节,但是只用到25个字节,前24个字节用来存储关联值,第25个字节用来存储成员值
var test = TestEnum3.test2(1, 2, 3)
// 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
test = .test1(1, 2, 3)
// 03 00 00 00 00 00 00 00
// 00 00 00 00 00 00 00 00
// 00 00 00 00 00 00 00 00
// 02
test = .test3(3)
// 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
test = .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
test = .test5

let stride = MemoryLayout<TestEnum3>.stride // 32
let size = MemoryLayout<TestEnum3>.size // 25
let alignment = MemoryLayout<TestEnum3>.alignment // 8

总结:

     var rawValue: Int {
         switch self {
         case .test1:
             return 0
         case .test2:
             return 1
         case .test3:
             return 2
         case .test4:
             return 3
         case .test5:
             return 4
         }
     }
上一篇下一篇

猜你喜欢

热点阅读