iOS Swift5 语法

Swift语法 Swift5 【04 - 枚举】

2020-05-08  本文已影响0人  Liwx

iOS Swift 语法 底层原理内存管理分析 专题:【iOS Swift5语法】

00 - 汇编
01 - 基础语法
02 - 流程控制
03 - 函数
04 - 枚举
05 - 可选项
06 - 结构体和类
07 - 闭包
08 - 属性
09 - 方法
10 - 下标
11 - 继承
12 - 初始化器init
13 - 可选项


目录


01-枚举的基本用法

// 写法1
enum Direction {
    case north
    case south
    case east
    case west
}

// 写法2
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")  // north
case .south:
    print("south")
case .east:
    print("east")
case .west:
    print("west")
}

02-关联值(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: 2020, month: 1, day: 2)
date = .string("2020-01-03")
switch date {
case .digit(var year, let month, let day):  // year var
    print(year, month, day)
case let .string(value):
    print(value)
}  // 2020-01-03

03-关联值举例

enum Password {
    case number(Int, Int, Int, Int)
    case gesture(String)
}

var pwd = Password.number(3, 5, 7, 8)
pwd = .gesture("12369")

switch pwd {
case let .number(n1, n2, n3, n4):
    print("number is ", n1, n2, n3, n4)
case let .gesture(str):
    print("gesture is ", str)
}

04-原始值(Raw Values)

// PokerSuit的原始值类型为Character
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) // ♣︎
// Grade的原始值类型为String
enum Grade : String {
    case perfect = "A"
    case great = "B"
    case good = "C"
    case bad = "D"
}

print(Grade.perfect.rawValue)   // A
print(Grade.great.rawValue)     // B
print(Grade.good.rawValue)      // C
print(Grade.bad.rawValue)       // D

05-隐式原始值(Implicitly Assigned Raw Values)

// 写法1
enum Direction : String {
    case north = "north"
    case south = "south"
    case east = "east"
    case west = "west"
}

// 写法2 等价于写法1
enum Direction : String {
    case north, south, east, west
}
print(Direction.north)  // north
print(Direction.north.rawValue) // north
enum Season : Int {
    case spring, summer, autumn, winter
}
print(Season.spring.rawValue)   // 0
print(Season.summer.rawValue)   // 1
print(Season.autumn.rawValue)   // 2
print(Season.winter.rawValue)   // 3
enum Season : Int {
    case spring = 1, summer, autumn = 4, winter
}
print(Season.spring.rawValue)   // 1
print(Season.summer.rawValue)   // 2
print(Season.autumn.rawValue)   // 4
print(Season.winter.rawValue)   // 5

06-递归枚举(Recursive Enumeration)

enum ArithExpr {
    case number(Int)
    indirect case sum(ArithExpr, ArithExpr)
    indirect case difference(ArithExpr, ArithExpr)
}
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 difference = 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)  // 枚举递归调用
    }
}

calculate(difference)   // 7

07-内存布局(MemoryLayout)

enum Password {
    case num(Int, Int, Int, Int)
    case other
}

MemoryLayout<Password>.stride   // 40, 分配占用的空间大小
MemoryLayout<Password>.size     // 33, 实际用的空间大小
MemoryLayout<Password>.alignment// 8, 内存对齐

var pwd = Password.num(9, 8, 6, 4)
pwd = .other
MemoryLayout.stride(ofValue: pwd)// 40, 分配占用的空间大小
MemoryLayout.size(ofValue: pwd) // 33, 实际用的空间大小
MemoryLayout.alignment(ofValue: pwd)// 8, 内存对齐


var a = 10
print(a)    // 这边打断点观察
// Int型变量a内存分配8字节
// 0A 00 00 00 00 00 00 00
image.png
enum TestEnum {
    case test1, test2, test3
}

var t = TestEnum.test1  // 内存: 00
t = .test2  // 内存: 01
t = .test3  // 内存: 02

print(Mems.ptr(ofVal: &t))  // 内存: 02

print(MemoryLayout<TestEnum>.size)  // 这边打断点观察  1
print(MemoryLayout<TestEnum>.stride)    // 1
print(MemoryLayout<TestEnum>.alignment) // 1
image.png
enum TestEnum1 : Int {  // 原始值为Int
    case test1 = 1, test2 = 2, test3 = 3
}

var t1 = TestEnum1.test1    // 内存: 00
print(Mems.ptr(ofVal: &t1))
t1 = .test2 // 01
t1 = .test3 // 02
// - 原始值不影响枚举变量内存存储

print(MemoryLayout<TestEnum1>.size)         // 1 断点观察
print(MemoryLayout<TestEnum1>.stride)       // 1
print(MemoryLayout<TestEnum1>.alignment)    // 1
image.png
enum TestEnum2 {
    case test1(Int, Int, Int)
    case test2(Int, Int)
    case test3(Int)
    case test4(Bool)
    case test5
}

print(MemoryLayout<TestEnum2>.size)         // 25
print(MemoryLayout<TestEnum2>.stride)       // 32
print(MemoryLayout<TestEnum2>.alignment)    // 8

var t2 = TestEnum2.test1(1, 2, 3)
print(Mems.ptr(ofVal: &t2))
// 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// 成员值,类似索引值

// Mems.memStr内存里面的内容
print(Mems.memStr(ofVal: &t2))
// 0x0000000000000001 0x0000000000000002 0x0000000000000003 0x0000000000000000

print(Mems.memStr(ofVal: &t2, alignment: .one))
// 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

t2 = .test2(4, 5)
// 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// 成员值,类似索引值

t2 = .test3(6)
// 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// 成员值,类似索引值

t2 = .test4(true)
// 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// 成员值,类似索引值

t2 = .test5
// 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// 成员值,类似索引值

print(t2)

enum TestEnum3 {
    case test
}

var t3 = TestEnum3.test
print(Mems.ptr(ofVal: &t3)) // 0x0000000000000001
print(t3)

print(MemoryLayout<TestEnum3>.size)         // 0 实际没有用到内存
print(MemoryLayout<TestEnum3>.stride)       // 1
print(MemoryLayout<TestEnum3>.alignment)    // 1

enum TestEnum4 {
    case test(Int)
}

var t4 = TestEnum4.test(10)
print(Mems.ptr(ofVal: &t4))
print(t4)

print(MemoryLayout<TestEnum4>.size)         // 8
print(MemoryLayout<TestEnum4>.stride)       // 8
print(MemoryLayout<TestEnum4>.alignment)    // 8

enum TestEnum5 {
    case test1(Int, Int, Int)
    case test2(Int, Int)
    case test3(Int)
    case test4(Bool)
    case test5
}

// - 通过枚举的成员值(类似索引值)来判断要执行哪个case
// - TestEnum5.test2(10, 20) 仅仅只是内存赋值操作, 不存在函数调用
var t5 = TestEnum5.test2(10, 20)
switch t5 {
case let .test1(v1, v2, v3):
    print("test1", v1, v2, v3)
case let .test2(v1, v2):
    print("test2", v1, v2)
case let .test3(v1):
    print("test3", v1)
case let .test4(v1):
    print("test4", v1)
case let .test5:
    print("test5")
} // test2 10 20
image.png

iOS Swift 语法 底层原理内存管理分析 专题:【iOS Swift5语法】

下一篇: 05 - 可选项
上一篇: 03 - 函数


上一篇下一篇

猜你喜欢

热点阅读