Swift教程之枚举类型详解_Swift

枚举定义了一个常用的具有相关性的一组数据,并在你的代码中以一个安全的方式使用它们。

如果你熟悉C语言,你就会知道,C语言中的枚举指定相关名称为一组整数值。在Swift中枚举更为灵活,不必为枚举的每个成员提供一个值。如果一个值(被称为“原始”的值)被提供给每个枚举成员,则该值可以是一个字符串,一个字符,或者任何整数或浮点类型的值。

另外,枚举成员可以指定任何类型,每个成员都可以存储的不同的相关值,就像其他语言中使用集合或变体。你还可以定义一组通用的相关成员为一个枚举,每一种都有不同的一组与它相关的适当类型的值的一部分。

在Swift中枚举类型是最重要的类型。它采用了很多以前只有类才具有的特性,如计算性能,以提供有关枚举的当前值的更多信息,方法和实例方法提供的功能相关的枚举表示的值传统上支持的许多功能。枚举也可以定义初始化,以提供一个初始成员值;可以在原有基础上扩展扩大它们的功能;并使用协议来提供标准功能。

欲了解更多有关这些功能,请参见Properties, Methods, Initialization, Extensions, Protocols

1、枚举语法

使用枚举enum关键词并把他们的整个定义在一对大括号内:

复制代码 代码如下:

enum SomeEnumeration {
    // enumeration definition goes here
}

下面是一个指南针的四个点一个例子:

复制代码 代码如下:

 
enum CompassPoint {
    case North
    case South
    case East
    case West
}

在枚举中定义的值(如North,South,East和West)是枚举的成员值(或成员)。这个例子里case关键字表示成员值一条新的分支将被定义。

Note

不像C和Objective-C,Swift枚举成员在创建时不分配默认整数值。在上面的例子CompassPoints中North,South,Eath,West不等于隐含0,1,2和3,而是一种与CompassPoint明确被定义的类型却各不相同的值。

多个成员的值可以出现在一行上,用逗号分隔:

复制代码 代码如下:

 
enum Planet {
    case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

每个枚举定义中定义了一个全新的类型。像其他Swift的类型,它们的名称(如CompassPoint和Planet)应为大写字母。给枚举类型单数而不是复数的名字,这样理解起来更加容易如:

复制代码 代码如下:

var directionToHead = CompassPoint.West

使用directionToHead的类型时,用CompassPoint的一个可能值初始化的推断。一旦directionToHead被声明为一个CompassPoint,您可以将其设置为使用更短的.语法而不用再书写枚举CompassPoint值本身:

复制代码 代码如下:

directionToHead = .East

directionToHead的类型是已知的,所以你可以在设定它的值时,不写该类型。使用类型明确的枚举值可以让代码具有更好的可读性。

2、匹配枚举值与switch语句

你可以使用单个枚举值匹配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"

你可以理解这段代码:

“考虑directionToHead的价值。当它等于North,打印“Lots of planets have a north”。当它等于South,打印“Watch out for penguins”等等。

正如控制流所描述,Switch语句考虑枚举的成员,如果省略了West时,这段代码无法编译,因为它没有考虑CompassPoint成员的完整性。Switch语句要求全面性确保枚举成员,避免不小心漏掉情况发生。

当它不需要为每一个枚举成员都匹配的情况下,你可以提供一个默认default分支来涵盖未明确提到的任何成员:

复制代码 代码如下:

 
let somePlanet = Planet.Earth
switch somePlanet {
case .Earth:
    println("Mostly harmless")
default:
    println("Not a safe place for humans")
}
// prints "Mostly harmless"

3、关联值

在上一节中的示例延时了一个枚举的成员是如何被定义(分类)的。你可以为Planet.Earth设置一个常量或变量,然后在代码中检查这个值。但是,它有时是有用的才能存储其它类型的关联值除了这些成员的值。这让你随着成员值存储额外的自定义信息,并允许在你的代码中来使用该信息。

Swift的枚举类型可以由一些数据类型相关的组成,如果需要的话,这些数据类型可以是各不相同的。枚举的这种特性跟其它语言中的奇异集合,标签集合或者变体相似

例如,假设一个库存跟踪系统需要由两种不同类型的条形码来跟踪产品。有些产品上标有UPC-A代码格式,它使用数字0到9的一维条码,每一个条码都有一个“数字系统”的数字,后跟十“标识符”的数字。最后一位是“检查”位,以验证代码已被正确扫描:

其他产品都贴有二维条码QR码格式,它可以使用任何的ISO8859-1字符,并可以编码字符串,最多2,953个字符:

这将是方便的库存跟踪系统能够存储UPC-A条码作为三个整数的元组,和QR代码的条形码的任何长度的字符串。

在Swift中可以使用一个枚举来定义两种类型的产品条形码,结构可以是这样的:

复制代码 代码如下:

enum Barcode {
    case UPCA(Int, Int, Int)
    case QRCode(String)
}

这可以被理解为:

“定义一个名为条形码枚举类型,它可以是UPC-A的任一值类型的关联值(Int,Int,Int),或QRCode的一个类型为String的关联值。”

这个定义不提供任何实际的Int或String值,它只是定义了条形码常量和变量当等于Barcode.UPCA或Barcode.QRCode关联值的类型的时候的存储形式。

然后可以使用任何一种类型来创建新的条码:

复制代码 代码如下:

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

此示例创建一个名为productBarcode新的变量,并与相关联的元组值赋给它Barcode.UPCA的值(8,8590951226,3)。提供的“标识符”值都有整数加下划线的文字,85909_51226,使其更易于阅读的条形码。

同一产品可以分配不同类型的条形码:

复制代码 代码如下:

 
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")

在这一点上,原来Barcode.UPCA和其整数值被新的Barcode.QRCode及其字符串值代替。_条形码的常量和变量可以存储任何一个_UPCA或QRCode的(连同其关联值),但它们只能存储其中之一在任何指定时间。

不同的条码类型像以前一样可以使用一个switch语句来检查,但是这一次相关的值可以被提取作为switch语句的一部分。您提取每个相关值作为常数(let前缀)或变量(var前缀)不同的情况下,在switch语句的case代码内使用:

复制代码 代码如下:

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).")
}
// prints "QR code with value of ABCDEFGHIJKLMNOP."

如果所有的枚举成员的关联值的提取为常数,或者当所有被提取为变量,为了简洁起见,可以放置一个var,或let标注在成员名称前:

复制代码 代码如下:

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

4、原始值

在关联值的条形码的例子演示了一个枚举的成员如何能声明它们存储不同类型的关联值。作为替代关联值,枚举成员可以拿出预先填入缺省值(称为原始值),从而具有相同的类型。

这里是一个存储原始的ASCII值命名枚举成员的一个例子:

复制代码 代码如下:

 
enum ASCIIControlCharacter: Character {
    case Tab = "\t"
    case LineFeed = "\n"
    case CarriageReturn = "\r"
}

在这里,原始值被定义为字符类型的枚举叫做ASCIIControlCharacter,并设置了一些比较常见的ASCII控制字符。字符值的字符串和字符的描述。

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

原始值可以是字符串,字符,或任何整数或浮点数类型。每个原始值必须在它的枚举中唯一声明。当整数被用于原始值,如果其他​​枚举成员没有值时,它们自动递增。

下面列举的是一个细化的早期Planet枚举,使用原始整数值来表示每个Planet的太阳系的顺序:

复制代码 代码如下:

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

自动递增意味着Planet.Venus具有2的原始值,依此类推。

访问其toRaw方法枚举成员的原始值:

复制代码 代码如下:

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

使用枚举的fromRaw方法来试图找到一个特定的原始值枚举成员。这个例子识别Uranus的位置通过原始值为7:

复制代码 代码如下:

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

然而,并非所有可能的Int值都会找到一个匹配的星球。正因如此,该fromRaw方法返回一个可选的枚举成员。在上面的例子中,是possiblePlanet类型Planet?或“可选的Planet”。

如果你试图找到一个Planet为9的位置,通过fromRaw返回可选的Planet值将是无:

复制代码 代码如下:

 
let positionToFind = 9
if let somePlanet = Planet.fromRaw(positionToFind) {
    switch somePlanet {
    case .Earth:
        println("Mostly harmless")
    default:
        println("Not a safe place for humans")
    }
} else {
    println("There isn't a planet at position \(positionToFind)")
}
// prints "There isn't a planet at position 9"

这个范例使用somePlanet= Planet.fromRaw(9)来尝试访问可选集合Planet,在可选Planet集合中设置检索条件somePlanet,在原始值为9的情况下,不能检索到位置为9的星球,所有else分支被执行。

时间: 2024-10-03 16:58:59

Swift教程之枚举类型详解_Swift的相关文章

Swift编程之枚举类型详解_Swift

想必写过程序的童鞋对枚举类型并不陌生吧,使用枚举类型的好处是多多的,在这儿就不做过多的赘述了.Fundation框架和UIKit中的枚举更是数不胜数,枚举可以使你的代码更易阅读并且可以提高可维护性.在Swift语言中的枚举可谓是让人眼前一亮.在Swift中的枚举不仅保留了大部分编程语言中枚举的特性,同时还添加了一些好用而且实用的新特性,在本篇文章中将领略一些Swift中枚举类型的魅力. 有小伙伴会问,不就是枚举么,有什么好说的.在Swift中的枚举怎不然,Swift中的枚举的功能要强大的多,不仅

Swift教程之集合类型详解_Swift

Swift 提供两种集合类型来存储集合,数组和字典.数组是一个同类型的序列化列表集合.字典是一个能够使用类似于键的唯一标识符来获取值的非序列化集合. 在Swift中,数组和字典的键和值都必须明确它的类型.这意味这数组和字典不会插入一个错误的类型的值,以致于出错.这也意味着当你在数组和字典中取回数值的时候能够确定它的类型. Swift 使用确定的集合类型可以保证代码工作是不会出错,和让你在开发阶段就能更早的捕获错误. note: Swift的数组 储存不同的类型会展示出不同的行为,例如变量,常量或

Swift教程之类与结构详解_Swift

类与结构是编程人员在代码中会经常用到的代码块.在类与结构中可以像定义常量,变量和函数一样,定义相关的属性和方法以此来实现各种功能. 和其它的编程语言不太相同的是,Swift不需要单独创建接口或者实现文件来使用类或者结构.Swift中的类或者结构可以在单文件中直接定义,一旦定义完成后,就能够被直接其它代码使用. 注意:一个类的实例一般被视作一个对象,但是在Swift中,类与结构更像是一个函数方法,在后续的章节中更多地是讲述类和结构的功能性. 1.类和结构的异同 类和结构有一些相似的地方,它们都可以

Swift教程之基础数据类型详解_Swift

基础类型 虽然Swift是一个为开发iOS和OS X app设计的全新编程语言,但是Swift的很多特性还是跟C和Objective-C相似. Swift也提供了与C和Objective-C类似的基础数据类型,包括整形Int.浮点数Double和Float.布尔类型Bool以及字符串类型String.Swift还提供了两种更强大的基本集合数据类型,Array和Dictionary,更详细的内容可以参考:Collection Types. 跟C语言一样,Swift使用特定的名称来定义和使用变量.同

Swift教程之基本运算符详解_Swift

运算符是一种特定的符号或表达式,用来检验.修改或合并变量.例如,用求和运算符+可以对两个数字进行求和(如let i = 1 + 2):稍微复杂一点的例子有逻辑与操作符&& (如if enteredDoorCode && passedRetinaScan) ,自增长运算符 ++i (这是i=i+1的简写方式) Swift支持C标准库中的大多数运算符并提升了各自的兼容性,从而可以排除常见的编码错误.赋值操作符 (=)不会返回一个值,这样可以防止你因粗心将赋值运算符 (=)写成

详解Swift中enum枚举类型的用法_Swift

一.引言 在Objective-C语言中,没有实际上是整型数据,Swift中的枚举则更加灵活,开发者可以不为其分配值类型把枚举作为独立的类型来使用,也可以为其分配值,可以是字符,字符串,整型或者浮点型数据. 二.枚举语法 Swift中enum关键字来进行枚举的创建,使用case来创建每一个枚举值,示例如下: //创建姓氏枚举,和Objective-C不同,Swift枚举不会默认分配值 enum Surname { case 张 case 王 case 李 case 赵 } //创建一个枚举类型的

Swift类型创建之自定义一个类型详解_Swift

小伙伴们,Swift中的Bool类型有着非常重要的语法功能,并支撑起了整个Swift体系中的逻辑判断体系,经过老码的研究和学习, Bool类型本身其实是对基础Boolean类型封装,小伙伴们可能咬着手指头问老码,怎么一会Bool类型,一会Boolean类型,其区别在于,前者是基于枚举的组合类型,而后者则是基本类型,只有两种true和false. ####自定义原型 接下老码根据Bool的思想来创建一个OCBool类型,来让小伙伴们了解一下Swift中到底是怎么玩儿的. 来我们先看一下OCBool

Java魔法堂:枚举类型详解

一.前言   Java的枚举类型相对C#来说具有更灵活可配置性,Java的枚举类型可以携带更多的信息. // C# enum MyColor{ RED = 0, BLUE = 1 } Console.Write(MyColor.RED); // Java enum MyColor{ RED("Hot", 4), BLUE("SAD",8); private String mood; public String getMood{ return mood; } priv

python进阶教程之动态类型详解_python

动态类型(dynamic typing)是Python另一个重要的核心概念.我们之前说过,Python的变量(variable)不需要声明,而在赋值时,变量可以重新赋值为任意值.这些都与动态类型的概念相关. 动态类型 在我们接触的对象中,有一类特殊的对象,是用于存储数据的.常见的该类对象包括各种数字,字符串,表,词典.在C语言中,我们称这样一些数据结构为变量.而在Python中,这些是对象. 对象是储存在内存中的实体.但我们并不能直接接触到该对象.我们在程序中写的对象名,只是指向这一对象的引用(