基本用法

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: 9, day: 10)
date = .string("2011-09-10")
switch date {
case .digit(let year, let month, let day):
print(year, month, day)
case let .string(value):
print(value)
}
// 必要时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) //
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

隐式原始值(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, 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

递归枚举 (indirect)

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 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)

MemoryLayout

可以使用MemoryLayout获取数据类型占用的内存大小

enum Password {
case number(Int, Int, Int, Int)
case other
}
MemoryLayout<Password>.stride // 40, 分配占用的空间大小
MemoryLayout<Password>.size // 33, 实际用到的空间大小
MemoryLayout<Password>.alignment // 8, 对齐参数
var pwd = Password.number(9, 8, 6, 4)
pwd = .other
MemoryLayout.stride(ofValue: pwd) // 40
MemoryLayout.size(ofValue: pwd) // 33
MemoryLayout.alignment(ofValue: pwd) // 8

窥探枚举的内存

1、枚举有2个case及以上的情况

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

MemoryLayout<TestEnum>.stride       // 32, 分配占用的空间大小

MemoryLayout<TestEnum>.size         // 25, 实际用到的空间大小

MemoryLayout<TestEnum>.alignment // 8, 对齐参数

通过观察枚举变量e的内存布局:

test1

    // 1个字节存储成员值
// N个字节存储关联值(N取占用内存最大的关联值),任何一个case的关联值都共用这N个字节
// 共用体 // 小端:高高低低
// 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)

test2

    // 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)

test3

    // 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)

test4

    // 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)

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
e = .test5

2、枚举只有1个case的情况(其实一个case也多大意义了)

enum TestEnum {
case test1(Int, Int, Int)
} var e = TestEnum.test1(10, 20, 30) MemoryLayout.stride(ofValue: e) // 24, 分配占用的空间大小
MemoryLayout.size(ofValue: e) // 24, 实际用到的空间大小
MemoryLayout.alignment(ofValue: e) // 8, 对齐参数

test1

// 0A 00 00 00 00 00 00 00
// 14 00 00 00 00 00 00 00
// 1E 00 00 00 00 00 00 00
var e = TestEnum.test1(10, 20, 30)

这种情况就不需要存储成员值了,直接开辟24个字节存关联值

Swift开发基础04-枚举的更多相关文章

  1. swift开发多线程篇 - 多线程基础

    swift开发多线程篇 - 多线程基础 iOS 的三种多线程技术 (1)NSThread  使用NSThread对象建立一个线程非常方便 但是!要使用NSThread管理多个线程非常困难,不推荐使用 ...

  2. Swift语法基础入门一(适合有C, OC开发人员)

    Swift开发体验 /*: 创建对象 * OC: alloc initWithXXX 方法 * Swift: (xxx:) */ /*: 调用方法 * OC: [UIColor redColor]; ...

  3. Swift零基础教程2019最新版(一)搭建开发环境

    Swift简单介绍 Swift是苹果强力推荐的新型开发语言,能开发苹果下属所有软件平台(iOS,iPadOS,macOS,watchOS,tvOS)初学者如果想进入苹果的开发体系,从Swift开始学习 ...

  4. 《Swift开发指南》

    <Swift开发指南> 基本信息 作者: 关东升    赵志荣 丛书名: 图灵原创 出版社:人民邮电出版社 ISBN:9787115366245 上架时间:2014-8-5 出版日期:20 ...

  5. Swift之基础知识

    Swift之基础知识 出于对Swift3.0的学习,写下这篇基本语法的笔记.希望能帮助记忆 -0- 这边提供Swift3.0中文教材,资源链接: https://pan.baidu.com/s/1c2 ...

  6. Swift开发语法

    Swift开发入门 简介 Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X 和 iOS 应用程序 2014 年,在 Apple WWDC 发布 历史 2010 年 7 月,苹果开发者 ...

  7. 《Swift开发指南》国内第一本Swift图书上市了

    <Swift开发指南>国内第一本Swift图书上市了 既<courseId=799262">苹果Swift编程语言开发指南>视频教程地址:courseId=79 ...

  8. Swift 开发语法

    文/Tuberose(简书作者)原文链接:http://www.jianshu.com/p/5e2d4c34f18e著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 简介 Swift 语 ...

  9. 3-MySQL DBA笔记-开发基础

    第二部分 开发篇 本篇首先讲述数据库开发的一些基础知识,如关系数据模型.常用的SQL语法.范式.索引.事务等,然后介绍编程开发将会涉及的数据库的一些技巧,最后结合生产实际,提供一份开发规范供大家参考. ...

  10. IOS开发基础知识碎片-导航

    1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...

随机推荐

  1. IPv6 — 协议头

    目录 文章目录 目录 前文列表 IPv6 协议头格式 扩展报头 前文列表 <IPv6 - 网际协议第 6 版> <IPv6 - 地址格式与寻址模式> IPv6 协议头格式 IP ...

  2. angular响应式表单笔记

    angular 在开发过程中对于表单的验证 import {ReactiveFormsModule, FormsModule, FormControl, FormGroup, Validators} ...

  3. nginx 常见配置案例参考(优化)

    在NGINX中,可以通过配置文件和特定的指令来实现权限控制.以下是一些常见的权限控制方法: 使用deny指令: 在NGINX配置文件中,可以使用deny指令来拒绝特定IP地址或IP地址范围的访问.可以 ...

  4. Python:Python中的参数屏蔽

    我们有时会不经意间写下如下代码: def update_indices(indices): indices = [] # 像在更新indices前先将其置空 for i in range(10): i ...

  5. 前端使用 Konva 实现可视化设计器(11)- 对齐效果

    这一章补充一个效果,在多选的情况下,对目标进行对齐.基于多选整体区域对齐的基础上,还支持基于其中一个节点进行对齐. 请大家动动小手,给我一个免费的 Star 吧~ 大家如果发现了 Bug,欢迎来提 I ...

  6. RocketMq开启安全认证ACL-解决服务器系统安全漏洞

    1.为什么要开启ACL 通过之前的文章我们已经知道怎么安装RocketMq了.如果你还不会安装RocketMq可以查看我的这篇文章:快速入门一篇搞定RocketMq-实现微服务实战落地 进行软件安装, ...

  7. HTML——select下拉选择标签

    select的基本语法: <select> <option></option> </select> 例子: <p>籍贯: <selec ...

  8. TS码流解析(三)PES

    我们常说的音视频数据流在TS中被称为Elementary Stream(ES),也称为原始码流(裸流).ES流本身不含有传输所需的所有信息,为了在传输过程中同时携带PTS(Presentation T ...

  9. nginx aio模块添加与配置

    1. 升级目的 让现有服务平滑过渡到高版本,减少服务漏洞,提高服务性能 让其支持nginx最新特性 nginx threads模块 2. 获取nginx1.7.2版本 wget http://ngin ...

  10. UIScrollView 在Autolayout下使用的一些问题

    一.UIScrollView 双指放大手势,双击放大实现 在设置UIScrollView的frame后.maxZoomScale 和 minZoomScale之后,UIScrollView会自然支持双 ...