枚举

一个枚举为一组相关联的值定义一个通用类型,并且让你可以在代码中类型安全地操作这些值。

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学习笔记十的更多相关文章

  1. Swift学习笔记十五

    自动引用计数(Automatic Reference Counting) 和OC一样,Swift用自动引用计数机制来跟踪和管理你应用程序的内存,大多数情况下,你不需要考虑自己管理内存,Swift会自动 ...

  2. Swift学习笔记十四

    Deinitialization 当类的实例对象即将要被释放时,会立即调用deinitializer,通过deinit关键字来定义deinitializer,和initializer一样,它也只存在于 ...

  3. Swift学习笔记十二

    方法 方法就是和某种特定类型相关联的函数.类.结构体.枚举都可以定义实例方法和类型方法.类型方法和OC中的类方法类似. 结构体和枚举也可以定义方法是Swift与C/OC之间很大的一个区别,在OC中,只 ...

  4. Swift学习笔记十六:协议

    Protocol(协议)用于统一方法和属性的名称,而不实现不论什么功能. 协议可以被类.枚举.结构体实现.满足协议要求的类,枚举,结构体被称为协议的遵循者. 遵循者须要提供协议指定的成员,如属性,方法 ...

  5. Swift 学习笔记十五:扩展

    扩展就是向一个已有的类.结构体或枚举类型加入新功能(functionality).扩展和 Objective-C 中的分类(categories)相似.(只是与Objective-C不同的是,Swif ...

  6. Swift学习笔记十四:构造(Initialization)

         类和结构体在实例创建时,必须为全部存储型属性设置合适的初始值. 存储型属性的值不能处于一个未知的状态.     你能够在构造器中为存储型属性赋初值,也能够在定义属性时为其设置默认值.下面章节 ...

  7. Swift学习笔记十:属性

    1.存储属性       1. 作为特定类或结构实例的一部分,存储属性存储着常量或者变量的值. 存储属性可分为变量存储属性(keywordvar描写叙述)和常量存储属性(keywordlet描写叙述) ...

  8. 【swift学习笔记】二.页面转跳数据回传

    上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...

  9. python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例

    python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例 新浪爱彩双色球开奖数据URL:http://zst.aicai.com/ssq/openInfo/ 最终输出结果格 ...

随机推荐

  1. markdown插件学习

    1.Markdown的定义 Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式.它用简洁的语法代替排版,而不像一般我们用的字处理软件Wo ...

  2. [再寄小读者之数学篇](2014-11-24 Abel 定理)

    设幂级数 $\dps{g(x)=\sum_{n=0}^\infty a_nx^n}$ 在 $|x|<1$ 内收敛, 且 $\dps{\sum_{n=0}^\infty a_n=s}$ 收敛. 则 ...

  3. HashBiMap

    HashBiMap  AbstractMap类实现了Map接口定义的一些方法,而BiMap类定义了其子类需要实现的一些方法,使得所有实现BiMap的类必须符合其独有的特性:键.值都是唯一的.HashB ...

  4. 匿名函数自执行原理和instanceof运算符执行原理

    今天收到RSS订阅中有一篇<Javascript – Arraylike的7种实现>,看第一种实现方式是,瞬间被!function(){}()这种匿名函数自执行方式给亮瞎了眼睛.这种写法绝 ...

  5. FreeMarker笔记 第四章 其它

    4.1 自定义指令 4.1.1 简介 自定义指令可以使用macro指令来定义.Java程序员若不想在模板中实现定义指令,而是在Java语言中实现指令的定义,这时可以使用freemarker.templ ...

  6. PDF数据提取------3.解析Demo

    1.PDF中文本字符串格式中关键值信息抓取(已完成) 简介:这种解析比较传统最简单主要熟练使用Regular Expression做语义识别和验证.例如抓取下面红色圈内关键信息 string mett ...

  7. 【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 ...

  8. 排列组合+组合数取模 HDU 5894

    // 排列组合+组合数取模 HDU 5894 // 题意:n个座位不同,m个人去坐(人是一样的),每个人之间至少相隔k个座位问方案数 // 思路: // 定好m个人 相邻人之间k个座位 剩下就剩n-( ...

  9. 牛课--C/C++

    引用是除指针外另一个可以产生多态效果的手段. //引用是除指针外另一个可以产生多态效果的手段. #include<iostream> using namespace std; class ...

  10. 著名加密库收集 Encrypt

    CryptoAPI 微软的CryptoAPI crypt32.lib,advapi32.lib,cryptui.lib #include <wincrypt.h>#include < ...