枚举

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

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. ylb:SQL Server中的时间函数

    ylbtech-SQL Server:SQL Server-SQL Server中的时间函数 SQL Server中的时间函数. 1,SQL Server中的时间函数 返回顶部 1.   当前系统日期 ...

  2. mysql优化SQL语句的一般步骤及常用方法

    一.优化SQL语句的一般步骤 1. 通过show status命令了解各种SQL的执行频率 mysqladmin extended-status 或: show [session|global]sta ...

  3. jquery图片裁切+PHP文件上传

    下载地址:download.csdn.net/source/2745353

  4. Android百度地图开发(一)环境搭建

    1.百度地图官方API文档下载 版本 使用说明 下载 Android SDK 通用资源下载 <离线地图>提供新版离线地图(百度矢量地图)与旧版离线地图(百度栅格地图)下载. 备注: 自An ...

  5. 面积最大的全1子矩阵--九度OJ 1497

    题目描述: 在一个M * N的矩阵中,所有的元素只有0和1,从这个矩阵中找出一个面积最大的全1子矩阵,所谓最大是指元素1的个数最多. 输入: 输入可能包含多个测试样例.对于每个测试案例,输入的第一行是 ...

  6. JS简单入门教程

    JS简单教程 使用方法:放到任意html页面的head标签下 Test1方法弹出当前时间对话框 Test2方法for循环输出 Test3方法for(…in…)输出数组内容 <script typ ...

  7. Linux 的 screen用法

    screen可以将任务挂起,即将任务放在后台,一般5个任务左右. 1.新建screen会话:直接输入screen命令或者screen -S [会话名称] 2.退出会话:按下组合键Ctrl+a并松开,此 ...

  8. enum 使用

    1.说明 enum是一个基本的关键字,却一直没弄清楚怎么用,这次在实现二叉树框架时需要用到常量,特地搜了一下,终于知道怎么用了. 2.enum使用要点 enum声明是一个类型,不是变量. enum经常 ...

  9. [ZZ] C++ pair

    Pair类型概述 pair是一种模板类型,其中包含两个数据值,两个数据的类型可以不同,基本的定义如下: pair<int, string> a; 表示a中有两个类型,第一个元素是int型的 ...

  10. Chapter 5 Convert Image Set To LevelDB/LMDB

    Caffe中convert_imageset projrct将图像数据转换成Caffe能读取的数据格式leveldb/lmdb 1.添加命令参数 在main函数中添加命令参数,内容和位置如下: #if ...