Swift学习笔记十
枚举
一个枚举为一组相关联的值定义一个通用类型,并且让你可以在代码中类型安全地操作这些值。
C中的枚举将关联的名字指派给一系列整型值。Swift中的枚举类型更为活泼,并不需要为每个成员指定值,如果指定值(raw value),这个值可以是String或者Character、整型或者浮点型。
此外,每个枚举成员可以指定不同数量的任意类型的关联值存储起来。这有点像其他语言里的联合。你可以定义一个普通的一系列关联值的集合作为一个枚举的一部分,每个枚举都可以有一个适当类型的不同集合。
在Swift中,枚举类型是一等类型(first class),他们拥有很多以前只有类才拥有的特性,比如属性用以给枚举的当前值提供额外的信息,以及实例方法给枚举所代表的值提供操作。枚举类型还可以提供初始化方法来提供初始化成员值,也可以被扩展来增加原始操作之外的操作,还可以遵守协议来提供标准操作。
枚举语法
用enum关键字来创建枚举,将所有的定义放在一对大括号内部:
enum CompassPoint {
case North
case South
case East
case West
}
case关键字意味着一行新的成员值就要被定义了,和C语言不一样的是,Swift中的枚举成员并不会在创建的时候就被赋给一个整型值,上面的例子中,North并不隐式地等于0,它们都是完全合法的值,都是一个明确定义的数据类型CompassPoint。
同一个case行可以有多个值,用逗号隔开即可。
像Swift中的其他数据类型名称一样,枚举型的名字应该以大写字母开头。
当把枚举成员赋值给某个变量后,这个变量的数据类型就可以被推断出为这个枚举类型,此后可以用简写的点语法来改变其值了:
var directionToHead = CompassPoint.West
directionToHead = .East
用switch语句匹配枚举值:
directionToHead = .South
switch directionToHead {
case .North:
println("Lots of planets have a north")
case .South:
println("Watch out for penguins")
case .East:
println("Where the sun rises")
case .West:
println("Where the skies are blue")
}
// prints "Watch out for penguins”
正如之前控制流中介绍的,当用switch语句处理枚举类型时,它必须全面的,比如如果省略掉case .West,那么就无法编译,因为switch语句并没有考虑到完整的枚举成员。这就防止了不小心漏掉了枚举成员。当然,在无法覆盖所有枚举成员的情况下,可以用一个default分支来处理。
关联值
前面的例子中,枚举成员都是自己本身作为自己的值。此外,还可以把变量/常量赋值给枚举成员,然后在其他地方使用它。但是,有时候会需要依靠这些成员值存储一些其他类型的关联值,这使得你可以依靠这些成员值存储额外的自定义信息,并且在每次使用成员时允许这个信息是不一样的。
你可以定义枚举存储任何已经定义的数据类型的关联值,并且每个枚举成员的关联值可以是不同类型的。比如下面的例子,定义了库存码的枚举类型,它有两个成员,一个代表一维条码(它总是可以用4个整型数字来标识),一个代表二维码(它总是可以用一个字符串来标识):
enum Barcode {
case UPCA(Int, Int, Int, Int)
case QRCode(String)
}
这里,枚举成员都有各自的关联值,定义的时候只需要指明关联值的类型,不需要给定值。这样,新的Barcode类型变量就可以创建为:
var productBarcode = Barcode.UPCA(, , , )
这里创建了一个变量,赋给它的值是一个有用关联元组(8, 85909, 51226, 3)的Barcode.UPCA,在此之后,这个变量就可以被赋值为不同的Barcode类型值了,比如:
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")
不同的Barcode类型仍然可以像之前那样在switch语句中被检查,这次,关联值可以被取出来成为switch语句的一部分。可以将关联值作为常量或者变量取出来以便在case体内部使用:
switch productBarcode {
case .UPCA(let numberSystem, let manufacturer, let product, let check):
println("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")
case .QRCode(let productCode):
println("QR code: \(productCode).")
}
// prints "QR code: ABCDEFGHIJKLMNOP.”
如果所有的关联值都是作为常量/变量被取出,则不需要在每个关联值前都写上var/let,将关键字提到前面:
switch productBarcode {
case let .UPCA(numberSystem, manufacturer, product, check):
println("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")
case let .QRCode(productCode):
println("QR code: \(productCode).")
}
// prints "QR code: ABCDEFGHIJKLMNOP.”
原始值(Raw Values)
如前所述,枚举成员可以定义不同类型的关联值。此外,还可以枚举成员也可以给定默认值(被称为raw value),这些值必须是同一类型的。比如:
enum ASCIIControlCharacter: Character {
case Tab = "\t"
case LineFeed = "\n"
case CarriageReturn = "\r"
}
注意原始值和关联值之间的区别,原始值是在定义枚举类型的时候就给出的,并且之后始终保持一致,关联值在定义枚举类型的时候并没有给出,而是在创建枚举类型变量的时候才赋予常量或者变量值。
原始值可以是字符串、字符、整数、浮点数。每个原始值必须在枚举声明内部是唯一的。如果原始值是整形的,那么如果有的成员没有赋原始值,系统会自动自增整形值赋给它们。比如:
enum Planet: Int {
case Mercury = , Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
这时系统会自动给后续成员依次赋原始值。通过rawValue可以获取成员的初始值,比如:
let earthsOrder = Planet.Earth.rawValue
// earthsOrder is 3
如果定义了一个有原始值类型的枚举类型,枚举会自动得到一个接受原始值类型参数并返回一个枚举成员或者nil的初始化方法,可以使用该方法视图创建一个枚举实例:
let possiblePlanet = Planet(rawValue: )
// possiblePlanet is of type Planet? and equals Planet.Uranus
并不是所有的整型数都能在枚举内部找到匹配的成员,所以,这个初始化方法返回的是可选枚举成员(optional enumeration member),
Swift学习笔记十的更多相关文章
- Swift学习笔记十五
自动引用计数(Automatic Reference Counting) 和OC一样,Swift用自动引用计数机制来跟踪和管理你应用程序的内存,大多数情况下,你不需要考虑自己管理内存,Swift会自动 ...
- Swift学习笔记十四
Deinitialization 当类的实例对象即将要被释放时,会立即调用deinitializer,通过deinit关键字来定义deinitializer,和initializer一样,它也只存在于 ...
- Swift学习笔记十二
方法 方法就是和某种特定类型相关联的函数.类.结构体.枚举都可以定义实例方法和类型方法.类型方法和OC中的类方法类似. 结构体和枚举也可以定义方法是Swift与C/OC之间很大的一个区别,在OC中,只 ...
- Swift学习笔记十六:协议
Protocol(协议)用于统一方法和属性的名称,而不实现不论什么功能. 协议可以被类.枚举.结构体实现.满足协议要求的类,枚举,结构体被称为协议的遵循者. 遵循者须要提供协议指定的成员,如属性,方法 ...
- Swift 学习笔记十五:扩展
扩展就是向一个已有的类.结构体或枚举类型加入新功能(functionality).扩展和 Objective-C 中的分类(categories)相似.(只是与Objective-C不同的是,Swif ...
- Swift学习笔记十四:构造(Initialization)
类和结构体在实例创建时,必须为全部存储型属性设置合适的初始值. 存储型属性的值不能处于一个未知的状态. 你能够在构造器中为存储型属性赋初值,也能够在定义属性时为其设置默认值.下面章节 ...
- Swift学习笔记十:属性
1.存储属性 1. 作为特定类或结构实例的一部分,存储属性存储着常量或者变量的值. 存储属性可分为变量存储属性(keywordvar描写叙述)和常量存储属性(keywordlet描写叙述) ...
- 【swift学习笔记】二.页面转跳数据回传
上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...
- python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例
python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例 新浪爱彩双色球开奖数据URL:http://zst.aicai.com/ssq/openInfo/ 最终输出结果格 ...
随机推荐
- markdown插件学习
1.Markdown的定义 Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式.它用简洁的语法代替排版,而不像一般我们用的字处理软件Wo ...
- [再寄小读者之数学篇](2014-11-24 Abel 定理)
设幂级数 $\dps{g(x)=\sum_{n=0}^\infty a_nx^n}$ 在 $|x|<1$ 内收敛, 且 $\dps{\sum_{n=0}^\infty a_n=s}$ 收敛. 则 ...
- HashBiMap
HashBiMap AbstractMap类实现了Map接口定义的一些方法,而BiMap类定义了其子类需要实现的一些方法,使得所有实现BiMap的类必须符合其独有的特性:键.值都是唯一的.HashB ...
- 匿名函数自执行原理和instanceof运算符执行原理
今天收到RSS订阅中有一篇<Javascript – Arraylike的7种实现>,看第一种实现方式是,瞬间被!function(){}()这种匿名函数自执行方式给亮瞎了眼睛.这种写法绝 ...
- FreeMarker笔记 第四章 其它
4.1 自定义指令 4.1.1 简介 自定义指令可以使用macro指令来定义.Java程序员若不想在模板中实现定义指令,而是在Java语言中实现指令的定义,这时可以使用freemarker.templ ...
- PDF数据提取------3.解析Demo
1.PDF中文本字符串格式中关键值信息抓取(已完成) 简介:这种解析比较传统最简单主要熟练使用Regular Expression做语义识别和验证.例如抓取下面红色圈内关键信息 string mett ...
- 【LeetCode】12 & 13 - Integer to Roman & Roman to Integer
12 - Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be wit ...
- 排列组合+组合数取模 HDU 5894
// 排列组合+组合数取模 HDU 5894 // 题意:n个座位不同,m个人去坐(人是一样的),每个人之间至少相隔k个座位问方案数 // 思路: // 定好m个人 相邻人之间k个座位 剩下就剩n-( ...
- 牛课--C/C++
引用是除指针外另一个可以产生多态效果的手段. //引用是除指针外另一个可以产生多态效果的手段. #include<iostream> using namespace std; class ...
- 著名加密库收集 Encrypt
CryptoAPI 微软的CryptoAPI crypt32.lib,advapi32.lib,cryptui.lib #include <wincrypt.h>#include < ...