Swift 枚举 可选项 ④

1. 枚举的基本用法

  • 常见枚举的定义及使用
enum Direction{
    case north
    case south
    case east
    case west
}
/*等同于
 enum Direction{
    case north, south, east, west
 }
 */
var dir  = Direction.north
dir = Direction.south
dir = .east  //因为已经确定了为Direction类型,也可以直接.east

2. 关联值(Associated Values)

  • 有时会将枚举的成员值跟其他类型的关联存储在一起。会非常有用
enum Score {
    case points(Int), grade(Character)
}
var score = Score.points(96)
//score = .grade("A")

switch score{
    case var .points(i):
        i = 95
        print(i, "points")
    case let .grade(i):
        print(i, "grade")
}
enum Date {
    case digit(year:Int, month:Int, day:Int)
    case string(String)
}

var date = Date.digit(year: 2020, month: 07, day: 22)


switch date{
 // case let Date.digit(y, m, d): let放在前面表示都为常量,必要时也可以var
    case  Date.digit(let y, let m, let d): 
        print(y,m,d)
    case  Date.string(let str):
        print(str)

}

3. 原始值(Raw Values)

  • 枚举成员可以使用相同类型的默认值预先关联,这个默认值叫做:原始值
enum  PokerSuit : Character {
    case  spade = "♠"
    case  heart = "❤"
    case  diamond = "♦"
    case  club = "♣"
}

var suit = PokerSuit.heart
print(suit)//heart
print(suit.rawValue)//❤
  • 隐式原始值,如果枚举的原始值类型是Int、 String,Swift会自动分配原始值
    注意:这里的Int String只是表明原始值类型,并不是指枚举类型
 enum Direction : String{
    case north, south, east, west
 }
/*等同于
enum Direction : String{
    case north = "north"
    case south = "south"
    case east = "east"
    case west = "west"
}
print(Direction.north)//north
print(Direction.north.rawValue)//north


enum Season : Int{
    case spring, summer, autumn, winter//默认:0 1 2 3 ;
    /*case spring = 1, summer, autumn = 4, winter  //1,2,4,5 也可以单独指定*/
}
print(Season.summer)//summer
print(Season.summer.rawValue)//1

 */

4. 递归枚举了解(Recursive Enumeration)

indirect enum ArithExpr {
    case number(Int)
    case sum(ArithExpr, ArithExpr)
    case difference(ArithExpr, ArithExpr)
}
/*等同于
 enum ArithExpr {
    case number(Int)
    indirect case sum(ArithExpr, ArithExpr)
    indirect 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 calculate(_ expr:ArithExpr) -> Int {
    switch expr {
        case let .number(value):
            return value
        case let .sum(left , right):
            return calculate(left) + calculate(right)
        case let .difference(left, right):
            return calculate(left) - calculate(right)
    }
}

let res = calculate(diff)  // 5 + 4 - 2 
print(res) //7

5. 关联值 原始值内存分配上的区别:

关联值会把对应的值直接存储到枚举变量里面,会占用内存
原始值并不是存储到枚举变量里面的,它只占用一个字节

enum Password {//关联值
    case num(Int, Int, Int ,Int)
    case other
}
enum Season : Int{//原始值 
    case spring = 2, summer , autumn = 5, winter
}


let passwordSize = MemoryLayout.size//实际占用的内存
let passwordSize2 = MemoryLayout.stride//系统分配的内存
let passwordSize3 = MemoryLayout.alignment//内存对齐

let seasonSize = MemoryLayout.size//实际占用的内存
let seasonSize2 = MemoryLayout.stride//系统分配的内存
let seasonSize3 = MemoryLayout.alignment//内存对齐

print("PasswordMemorySize:",passwordSize,passwordSize2,passwordSize3)
print("SeasonMemorySize:",seasonSize,seasonSize2,seasonSize3)
/*PasswordMemorySize: 33 40 8
SeasonMemorySize: 1 1 1*/

内存分配:

enum testEnumNum1 {
    case test1, test2, test3, test4
}
print("size1:",MemoryLayout.size)//实际占用的内存      1
print("stride1:",MemoryLayout.stride)//系统分配的内存  1
print("alignment1:",MemoryLayout.alignment)//内存对齐 1


var ten1 = testEnumNum1.test1
print(Mems.ptr(ofVal: &ten1))

ten1 = testEnumNum1.test2
ten1 = testEnumNum1.test3
ten1 = testEnumNum1.test4
print("============ 2 ===========")

enum testEnumNum2:Int {
    case test1, test2, test3, test4
}
print("size2:",MemoryLayout.size)//实际占用的内存      1
print("stride2:",MemoryLayout.stride)//系统分配的内存  1
print("alignment2:",MemoryLayout.alignment)//内存对齐 1

/*
 00 00 00 00 00 00 00 00
 */
var ten2 = testEnumNum2.test1
print(Mems.ptr(ofVal: &ten2))
/*
 01 00 00 00 00 00 00 00
 */
ten2 = testEnumNum2.test2
/*
 02 00 00 00 00 00 00 00
 */
ten2 = testEnumNum2.test3
ten2 = testEnumNum2.test4
print("============ 3 ===========")

/*
 1个字节存储成员值
 n个自己存储关联值(n取占用内存最大的关联值,任何一个case的关联值都公用这n个字节)
 */
enum testEnumNum3 {
    case test1(Int)
    case test2(Int,Int)
    case test3(Int,Int,Int)
    case test4(Bool)
    case test5
}
print("size3:",MemoryLayout.size)//实际占用的内存        25
print("stride3:",MemoryLayout.stride)//系统分配的内存    32
print("alignment3:",MemoryLayout.alignment)//内存对齐   8

/*
 01 00 00 00 00 00 00 00     //关联值
 00 00 00 00 00 00 00 00     //关联值
 00 00 00 00 00 00 00 00     //关联值
 
 00                          //成员值,第几个,从0开始
 00 00 00 00 00 00 00
 */
var ten3 = testEnumNum3.test1(1)
print(Mems.ptr(ofVal: &ten3))
/*
 02 00 00 00 00 00 00 00     //关联值
 03 00 00 00 00 00 00 00     //关联值
 00 00 00 00 00 00 00 00     //关联值
 
 01                          //成员值,第几个,从0开始
 00 00 00 00 00 00 00
 */
ten3 = testEnumNum3.test2(2,3)
/*
 02 00 00 00 00 00 00 00     //关联值
 03 00 00 00 00 00 00 00     //关联值
 04 00 00 00 00 00 00 00     //关联值
 
 02                          //成员值,第几个,从0开始
 00 00 00 00 00 00 00
 */
ten3 = testEnumNum3.test3(2,3,4)
ten3 = testEnumNum3.test4(true)
ten3 = testEnumNum3.test5

6 lldb 常用指令

  • 读取寄存器的值
register read/格式
register read/x
  • 修改寄存器的值
register write 寄存器名称 数值
register write rax 0
  • 读取内存中的值
x/数量-格式-字节大小 内存地址
x/3xw 0x0000010
  • 修改内存中的值
memory write 内存地址 数值
memory write 0x000010 10
  • 格式
x是16进制,f是浮点,d是十进制
  • 字节大小
b -byte 1字节
h -half word 2字节
w -word 4字节
g -giant word 8字节
  • po 表达式
po/x $rax
  • print 表达式

  • 线程调试指令

    • thread step-over 、 next 、 n 单步运算,把子函数当做整体一步执行(源码级别)

    • thread step-in 、 step 、s 单步运算,遇到子函数会进入函数(源码级别)

    • thread step-inst-over 、 nexti 、ni 单步运算,把子函数当做整体一步执行(汇编级别)

    • thread step-inst、 stepi 、si 单步运算,遇到子函数会进入函数(汇编级别)

    • thread step-out 、finish直接执行完单签函数的所有代码,返回上一个函数(遇到断点会卡主)

你可能感兴趣的:(Swift 枚举 可选项 ④)