Swift从入门到精通第三篇 - 枚举及内存布局

枚举及内存布局(学习笔记)

环境Xcode 11.0 beta4 swift 5.1

  • 枚举的基本用法

    enum Direction {
        case north
        case south
        case east
        case west
    }
    enum Direction {
        case north, south, east, west
    }
    // 以上两种写法是等价
    var dir = Direction.west
    dir = Direction.east
    dir = .north
    print(dir) // north
    switch dir {
    case .north:
        print("north")
    case .south:
        print("south")
    case .east:
        print("east")
    case .west:
        print("west")
    }
  • 关联值(Associated Values)
    • 有时将枚举的成员值跟其他类型的值关联存储在一起会非常有用
    enum Score {
        case points(Int)
        case grade(Character)
    }
    var score = Score.points(96)
    score = .grade("A")
    switch score {
    case let .points(i):
        print(i, "points")
    case let .grade(i):
        print("grade", i);
    } // grade A
    enum Date {
        case digit(year: Int, month: Int, day: Int)
        case string(String)
    }
    var date = Date.digit(year: 2011, month: 10, day: 7)
    date = .string("2011-10-7")
    switch date {
    case .digit(let year, let month, var day):
        print(year, month, day)
    case let .string(value):
        print(value)
    }
    // year month day 可以用 `let` 或者 `var` 修饰
  • 原始值(Raw Values)
    • 枚举成员可以使用相同类型的默认值预先对应,这个默认值叫做原始值, 原始值不占用枚举变量的内存
    enum PokerSuit : Character {
        case spade = "♠️"
        case heart = "♥️"
        case diamond = "♦️"
        case club = "♣️"
    }
    var suit = PokerSuit.spade
    print(suit) // spade
    print(suit.rawValue) // ♠️
    print(PokerSuit.club.rawValue) // ♣️
  • 隐式原始值(Implicitly Assigned Raw Values)
    • 如果枚举的原始值类型是Int、 String, Swift会自动分配原始值
    enum Direction : String {
        case north = "north"
        case south = "south"
        case east = "east"
        case west = "west"
    }
    // 上面的枚举变量的原始值等价下面
    enum Direction : String {
        case north, south, east, west
    }
    print(Direction.north) // north
    print(Direction.north.rawValue) // north
    enum Season : Int {
        case spring, summer, autumn = 4, winter
    }
    print(Season.spring.rawValue) // 0
    print(Season.summer.rawValue) // 1
    print(Season.autumn.rawValue) // 4
    print(Season.winter.rawValue) // 5
  • 递归枚举(Recursive Enumeration)
    • 使用关键字 indirect, 可以用在 enum 前面,也可以用在枚举成员变量前面(case 前面)
    indirect enum ArithExpr {
        case number(Int)
        case sum(ArithExpr, ArithExpr)
        case difference(ArithExpr, ArithExpr)
    }
    let five = ArithExpr.number(5)
    let four = ArithExpr.number(4)
    let two = ArithExpr.number(2)
    let sum = ArithExpr.sum(five, four)
    let diff = ArithExpr.difference(sum, two)
    func cal(_ expr: ArithExpr) -> Int {
        switch expr {
        case let .number(value):
            return value
        case let .sum(left, right):
            return cal(left) + cal(right)
        case let .difference(left, right)
            return cal(left) - cal(right)
        }
    }
    cal(difference) // 7
  • 枚举的内存布局

    enum TestEnum {
    case test0(Int, Int, Int)
    case test1(Int, Int)
    case test2(Int)
    case test3(Bool)
    case test4
    }
    print(MemoryLayout<TestEnum>.size)      // 25 实际用到的内存
    print(MemoryLayout<TestEnum>.stride)    // 32 申请分配的内存
    print(MemoryLayout<TestEnum>.alignment) // 8 内存对其参数
    // 一共申请32个字节,实际用到25个字节,实际要用到的内存要按关联值占用到的最大的内存,在本例中是test0最大,关联3个Int类型,在64位系统中每个Int占用8个字节
    // 因此要用24个字节,另外要一个字节即第25个字节用来标识枚举成员值,后面的7个字节用来内存补齐,以满足内存对齐
    // 小端模式
    // 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 (这一个字节标识枚举的成员值,0代表test0)
    // 00 00 00 00 00 00 00
    var t = TestEnum.test0(1, 2, 3)
    // 小端模式
    // 04 00 00 00 00 00 00 00
    // 04 00 00 00 00 00 00 00
    // 00 00 00 00 00 00 00 00
    // 01 (这一个字节标识枚举的成员值,1代表test1)
    // 00 00 00 00 00 00 00
    t = .test1(4, 5)
    // 小端模式
    // 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 (这一个字节标识枚举的成员值,2代表test2)
    // 00 00 00 00 00 00 00
    t = .test2(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 (这一个字节标识枚举的成员值,3代表test3)
    // 00 00 00 00 00 00 00
    t = .test3(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 (这一个字节标识枚举的成员值,4代表test4)
    // 00 00 00 00 00 00 00
    t = .test4

    [Swift从入门到精通]

转载于:https://www.cnblogs.com/tzsh1007/p/11459187.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值