枚举语法

你可以用enum开始并且用大括号包含整个定义体来定义一个枚举:

  1. enum SomeEnumeration {
  2. // 在这里定义枚举
  3. }

这里有一个例子,定义了一个包含四个方向的罗盘:

  1. enum CompassPoint {
  2. case North
  3. case South
  4. case East
  5. case West
  6. }

枚举中定义的变量(像上例中North, South, East, West)是枚举的成员变量(或者说成员).关键字case是用来标明这一行将要定义一个新的成员变量

注意:与C或者Objective-C不同的是,在Swift语言中枚举类型的成员初始的时候不会被默认赋值成整数值,在CompassPoint这个例子中,North, South, East, West默认不会隐式的等于0,1,2,3。取而代之的是不同的枚举成员将要用什么类型以及赋值什么值都是可以自己控制的,可以在定义CompassPoint这个枚举的时候指定.

多个成员还可以用一行来定义,他们之间用逗号分割:

  1. enum Plant{
  2. case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
  3. }

每个枚举的定义都是定义了一个全新的类型,就像Swfit中的其他的类型一样,枚举的名称(像上边的CompassPoint, Plant)应该是以一个大写字母开头,让他们是单数类型而不是复数类型,从而让他们可以不言而喻:

  1. var directionToHead = CompassPoint.West

当directionToHead在初始化过程中被赋值成CompassPoint中的某一个可能的值的时候,它的类型就可以被推测出来来了。一旦directionToHead被声明成是CompassPoint类型,那么你就可以简短的使用逗号表达式来给它赋值成其他的CompassPoint当中的值了:

  1. directionToHead = .East

directionToHead的类型是已知的了,所以你可以忽略它的类型来给他赋值了。这样使得在使用显示类型的枚举值时代码具有很高的可读性。

使用Switch语句来匹配枚举值

你可以通过switch语句来访问单独的某个枚举值:

  1. directionToHead = .South
  2. switch directionToHead {
  3. case .North:
  4. println("Lots of planets have a north")
  5. case .South:
  6. println("Watch out for penguins")
  7. case .East:
  8. println("Where the sun rises")
  9. case .West:
  10. println("Where the skies are blue")
  11. }
  12. // 输出"Watch out for penguins”

你可以这样阅读这段代码:考虑directionToHead的值,如果它等于.North那么就输出"Lost of planets have a north",如果它等于.South,那么就输出"Watch
out for penguins"。



就和在控制流程那一章所讲,一个switch语句被用到判断枚举值的时候,必须要包括所有的枚举成员。假设.West被忽略了,将会导致编译出错,因为它没有考虑到枚举的所有的枚举成员,我们需要全面性的确保枚举的所有成员不被忽略掉.



如果给考虑每个枚举的成员不合适,你可以提供一个default来覆盖其他没有明确处理的成员:

  1. let somePlanet = Planet.Earth
  2. switch somePlanet {
  3. case .Earth:
  4. println("Mostly harmless")
  5. default:
  6. println("Not a safe place for humans")
  7. }
  8. // 输出 "Mostly harmless"

关联值

在上一节的示例中显示了一个枚举的成员是如何在自己的权利界定(和类型)的值。你可以设置一个常量或变量的值为Planet.Earth ,然后检查这个值。然而,如果在保留成员值的同时能够存储其它类型的关联值将会变得更有意义。这使您能够在保存成员值的同时存储额外的自定义信息,并且允许每次你在代码中使用这些成员值的时候改变这些关联值。在Swift中当你定义一个枚举成员的时候,你可以给他关联任何的类型,而且如果需要的话每个成员可以有不同的关联类型。枚举类型的这个特性和其他语言当中的辨别联合,标记联合或者变体很像。



举个例子,设想一个库存跟踪系统想要通过两种不同的条形码来跟踪产品。一些产品用UPC-A格式的一维条形码标识的,使用0到9的数字。每个条形码当中有一个标识“数字系统“的数字,然后是10个“标识符"数字,最后边一个用来做“检查”的数字,以确保这个条形码被正确的扫描识别:





另一些产品是用QR编码格式的二维码标识的,这种条形码可以使用任何ISO 8859-1的字符而且最大可以编码一个2953字符长度的字符串:





如果能够用一个有三个整型的元组来存储UPC-A格式的条形码,然后用一个可以存储任意长度的字符串来存储QR格式的条形码,那么对于一个库存跟踪系统来说,将会是再便捷不过的了。



在Swift语言中,一个可以定义两个格式的产品条形码的枚举看起来是这样的:

  1. enum Barcode {
  2. case UPCA(Int, Int, Int)
  3. case QRCode(String)
  4. }

你可以这样阅读这段代码:定义了一个叫做Barcode的枚举类型,它可以有一个UPCA成员,这个成员关联了一个包含三个整型数值的元组,同时这个枚举类型还有一个QRCode成员,关联了一个字符串。



这个定义不会生成任何的整型或者字符串值,他只是定义了当一个不可变变量或者变量等于Barcode.UPCA或者Barcode.QRCode的时候它被关联的值的类型



这样一来可以用任意其中一个类型来生成一个新的条形码了:

  1. var productBarcode = Barcode.UPCA(8, 85909_51226, 3)

这个例子生成了一个新的变量叫做productBarcode,这个变量被关联了一个Barcode.UPCA类型的元组,这个元组的值为(8, 8590951226,
3),被提供做“标识”的值用下划线分割了-85909_51226,这样做是为了更好的被以条形码读出来。



同样的产品还可以被赋值为另一个条形码类型:

  1. productBarcode = .QRCode("ABCDEFGHIJKLMNOP")

在这一点上,原来的Barcode.UPCA以及关联到的整型值被一个新类型Barcode.QRCode以及与其关联的字符串给替换了。Barcode类型的不可变变量以及可变变量可以存储.UPCA或者.QRCode类型(同时还有与其相关联的值),但是每次都只能存储这两个类型当中的一个。



同样,这两个不同的类型可以用Switch语句来做检查。同时,在switch语句中他们相关联的值也可以被获取到。你可以把关联的值当做不可变变量(用let来开头),或者可变变量(用var开头)以在switch的控制体当中使用。

  1. switch productBarcode { case .UPCA(let numberSystem, let identifier, let check): println("UPC-A with value of \(numberSystem), \(identifier), \(check).") case .QRCode(let productCode): println("QR code with value of \(productCode).") }

如果一个枚举成员关联的所有值都被当做不可变变量或者可变变量来使用,那么你可以在成员名称之前只放一个let或者var来达到目的,简要示例:

  1. switch productBarcode {
  2. case let .UPCA(numberSystem, identifier, check):
  3. println("UPC-A with value of \(numberSystem), \(identifier), \(check).")
  4. case let .QRCode(productCode):
  5. println("QR code with value of \(productCode).")
  6. }
  7. // 输出 "QR code with value of ABCDEFGHIJKLMNOP.”

原始值

在上一节当中条形码的例子展示了一个枚举类型的成员怎么声明他们可以存储不同类型的关联值。不同于关联值,枚举类型的成员还可以预设置默认值(我们叫他原始值),这些值的类型是相同的。



这里有一个枚举成员存储一个ASCII值的例子:

  1. enum ASCIIControlCharacter: Character {
  2. case Tab = "\t"
  3. case LineFeed = "\n"
  4. case CarriageReturn = "\r"
  5. }

这里定义了一个原始值为字符类型的枚举类型ASCIIControlCharacter,而且包含了一些我们常用的控制字符。关于字符类型,你可以在字符串和字符那个章节找到更多的描述。



请注意,原始值与关联值不同。原始值应该是在你定义枚举的代码中被设置为预填充值的,就像上述三个ASCII码。对于一个特定的枚举成员的原始值始终是相同的。关联值是当你创建一个基于枚举的成员的新的常量或变量的时候设置的,并且每次都可以是不同的。



原始值可以是字符串,字符或者其他任何的整型或者浮点型等数字类型。每个原始值在他属的枚举类型定义的时候都应该是不同的。如果原始值是整数类型,那么当其他枚举成员没有设置原始值的时候,他们的原始值是这个整型原始值自增长设置的。



下边这个枚举类型是对之前的Plant枚举类型的改良,新的枚举类型有一个整型的原始值来标识他们在距离太阳的顺序:

  1. enum Planet: Int {
  2. case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
  3. }

自增长的意思就是Planet.Venus的原始值会被设置成2,以此类推。



可以通过枚举成员的toRaw()方法来获取他的原始值:

  1. let earthsOrder = Planet.Earth.toRaw()
  2. //eathsOrder is 3

使用枚举成员的fromRaw()方法来尝试通过一个原始值来寻找他所对应的枚举成员。下面这个例子介绍了怎么通过Uranus的原始值7找到Uranus的:

  1. let possiblePlanet = Planet.fromRaw(7)
  2. // possiblePlanet is of type Planet? and equals Planet.Uranus”

然而不是所有的整型值都可以找到一个对应的Planet,正是如此,fromRaw()将会返回一个非强制类型的枚举成员。上边展示的例子当中possiblePlanet是一个Planet?类型,或者是一个非强制Planet类型。



如果你尝试通过原始值9来寻找他对应的Planet,那么fromRaw()返回给你的非强制Planet类型将会是nil:

  1. let positionToFind = 9
  2. if let somePlanet = Planet.fromRaw(positionToFind) {
  3. switch somePlanet {
  4. case .Earth:
  5. println("Mostly harmless")
  6. default:
  7. println("Not a safe place for humans")
  8. }
  9. } else {
  10. println("There isn't a planet at position \(positionToFind)")
  11. }
  12. // 输出 "There isn't a planet at position 9”

这个例子尝试使用非强制类型绑定来试着用原始值9来获取一个Planet。表达式if let somePlanet = Planet.fromRaw(9)用来检索一个Planet,如果能够检索到Planet将会将这个非强制Planet赋值给somePlanet。在这个示例中,通过原始值9不可能检索到对应的Planet,所以else包含的语句将会被执行。

【iOS】swift 枚举的更多相关文章

  1. iOS Swift WisdomHUD 提示界面框架

    iOS Swift WisdomHUD 提示界面框架  Framework Use profile(应用简介) 一:WisdomHUD简介 今天给大家介绍一款iOS的界面显示器:WisdomHUD,W ...

  2. iOS Swift WisdomKeyboardKing 键盘智能管家SDK

    iOS Swift WisdomKeyboardKing 键盘智能管家SDK [1]前言:    今天给大家推荐个好用的开源框架:WisdomKeyboardKing,方面iOS日常开发,优点和功能请 ...

  3. iOS swift的xcworkspace多项目管理(架构思想)

    iOS  swift的xcworkspace多项目管理(架构思想) 技术说明: 今天在这里分享 swift下的 xcworkspace多项目管理(架构思想),能为我们在开发中带来哪些便捷?能为我们对整 ...

  4. iOS Swift 模块练习/swift基础学习

    SWIFT项目练习     SWIFT项目练习2 iOS Swift基础知识代码 推荐:Swift学习使用知识代码软件 0.swift中的宏定义(使用方法代替宏) 一.视图  +控件 1.UIImag ...

  5. ios swift 实现饼状图进度条,swift环形进度条

    ios swift 实现饼状图进度条 // // ProgressControl.swift // L02MyProgressControl // // Created by plter on 7/2 ...

  6. Building gRPC Client iOS Swift Note Taking App

    gRPC is an universal remote procedure call framework developed by Google that has been gaining inter ...

  7. iOS Swift WisdomScanKit图片浏览器功能SDK

    iOS Swift WisdomScanKit图片浏览器功能SDK使用 一:简介      WisdomScanKit 由 Swift4.2版编写,完全兼容OC项目调用. WisdomScanKit的 ...

  8. iOS Swift WisdomScanKit二维码扫码SDK,自定义全屏拍照SDK,系统相册图片浏览,编辑SDK

    iOS Swift WisdomScanKit 是一款强大的集二维码扫码,自定义全屏拍照,系统相册图片编辑多选和系统相册图片浏览功能于一身的 Framework SDK [1]前言:    今天给大家 ...

  9. iOS swift项目IM实现,从长连接到数据流解析分析之Socket

    iOS  swift项目IM实现,从长连接到底层数据解析分析之Socket 一:项目简介:  去年开始接手了一个国企移动项目,项目的需求是实现IM即时通讯功能. * 一期版本功能包括了:       ...

随机推荐

  1. Python Cookbook(第3版)中文版:15.15 C字符串转换为Python字符串

    15.15 C字符串转换为Python字符串¶ 问题¶ 怎样将C中的字符串转换为Python字节或一个字符串对象? 解决方案¶ C字符串使用一对 char * 和 int 来表示, 你需要决定字符串到 ...

  2. 洛谷P2617 Dynamic Ranking(主席树,树套树,树状数组)

    洛谷题目传送门 YCB巨佬对此题有详细的讲解.%YCB%请点这里 思路分析 不能套用静态主席树的方法了.因为的\(N\)个线段树相互纠缠,一旦改了一个点,整个主席树统统都要改一遍...... 话说我真 ...

  3. 【BZOJ4530】大融合(Link-Cut Tree)

    [BZOJ4530]大融合(Link-Cut Tree) 题面 讨厌权限题!!! Loj链接 题目描述 小强要在 N个孤立的星球上建立起一套通信系统.这套通信系统就是连接 N个点的一个树.这个树的边是 ...

  4. [BZOJ4071][APIO2015]八邻旁之桥

    BZOJ(这题是BZOJ权限题,有权限号的就去看看吧) Luogu(良心洛谷) 题目描述 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域\(A\)和区域\(B\). 每一块区域沿着河岸都建了恰好 ...

  5. [HNOI2015]亚瑟王

    题面在这里 题意 \(n\)张卡按照一定顺序排列,每轮从第\(1\)张开始考虑到最后一张,考虑一张卡时有\(p[i]\)的概率产生\(d[i]\)的贡献,产生贡献时直接退出该轮并在之后的考虑中直接跳过 ...

  6. Myeclipse插件快速生成ssh项目并配置注解 在action层注入service的超详细过程

    最近发现,我对于ssh的 自动注入配置 还是不熟悉,于是整理了一下 终于做了一个 简单的 注入配置出来. 以前都是在applicationContext.xml 里面这样配 <bean id=& ...

  7. Linux文件目录权限对比

    读取权限(r) 文件只有r权限: 具有读取\阅读文件内容权限1.只能使用查看类命令 cat.head.tail.less.more2.不能复制,也就是不能使用cp命令3.不能移动,不能使用mv命令移动 ...

  8. Android RecyclerView 滚动到中间位置

    最近看到QQ音乐的歌词每次滑动后都可以滚回到中间位置.觉得甚是神奇,打开开发者模式显示布局,发现歌词部分不是采用 android 控件的写的,应该是前端写的.于是,我想,能不能用 recyclerVi ...

  9. centos7 升级 git(2.14.3) 版本

    下载  wget https://www.kernel.org/pub/software/scm/git/git-2.14.3.tar.gz 安装依赖包  yum install curl-devel ...

  10. 筛法求素数Java

    输出:一个集合S,表示1~n以内所有的素数 import java.util.Scanner; public class 筛法求素数 { public static void main(String[ ...