您的位置:首页 > 移动开发 > Swift

swift基础笔记3-枚举

2016-05-24 14:38 337 查看
枚举定义了一个通用类型的一组相关值,使你可以在你的代码中以一种安全的方式来使用这些值。

Swift 中的枚举比C语言更加灵活,不必给每一个枚举成员提供一个值。如果给枚举成员提供一个值(称为“原始”值),则该值的类型可以是字符串,字符,或是一个整型值或浮点数。

此外,枚举成员可以指定任何类型的相关值存储到枚举成员值中,就像其他语言中的联合体(unions)和变体(variants)。你可以定义一组通用的相关成员作为枚举的一部分,每一组都有不同的一组与它相关的适当类型的数值。

枚举语法

例:

enum CompassPoint {

case North

case South

case East

case West

}

一个枚举中被定义的值(例如 North , South , East 和 West )是枚举的成员值(或者成员)。
case 关键词表明新的一行成员值将被定义。

多个成员值可以出现在同一行上,用逗号隔开。每个枚举定义了一个全新的类型。像 Swift 中其他类型一样,它们的名字(例如 CompassPoint 和 Planet )必须以一个大写字母开头


注意:和 C 和 Objective-C 不同,Swift 的枚举成员在被创建时不会被赋予一个默认的整型值。在上面的Points 例子中, North , South , East 和 West 不会隐式地赋值为了 0 , 1 , 2 和 3 。相反的,这些不同的枚举成员在 CompassPoint 的一种显示定义中拥有各自不同的值。

directionToHead 的类型可以在它被 CompassPoint 的一个可能值初始化时推断出来。一旦被声明为一个 CompassPoint ,你可以使用一个缩写语法(.)将其设置为另一个 CompassPoint 的值:

var directionToHead = CompassPoint.West

当 directionToHead 的类型已知时,再次为其赋值可以省略枚举名。使用显式类型的枚举值可以让代码具有更好的可读性。

directionToHead = .East

匹配枚举值和Switch语句

例:
directionToHead = .South 
switch directionToHead {
case .North:
<span style="white-space:pre">	</span>print("Lots of planets have a north")
case .South:
<span style="white-space:pre">	</span>print("Watch out for penguins") 
case .East:
<span style="white-space:pre">	</span>print("Where the sun rises") 
case .West:
<span style="white-space:pre">	</span>print("Where the skies are blue") }
// 输出 "Watch out for penguins”

相关值Associated Values

有时候能够把其他类型的相关值和成员值一起存储起来会很有用。这能让你
存储成员值之外的自定义信息,并且当你每次在代码中使用该成员时允许这个信息产生变化。


定义 Swift 的枚举存储任何类型的相关值,如果需要的话,每个成员的数据类型可以是各不相同的。

在 Swift 中,使用如下方式定义两种商品条码的枚举:

enum Barcode {

case UPCA(Int, Int, Int, Int)

case QRCode(String)

}

以上代码可以这么理解: 定义一个名为Barcode的枚举类型,它可以使UPCA的一个相关值(Int,Int,Int,Int),或者是QRCode的一个字符串类型(String)的相关值。

这个定义不提供任何Int或String的实际值,他只是定义了,当Barcode常量和变量等于Barcode.UPCA或Bracode.QRCode时,相关值的类型

例如,创建一个productBarcode的条码变量,并附给他一个Barcode.UPCA的相关元组值(8,83989,33434,3):

var productBarcode = Barcode.UPCA(8,83989,33434,3)

同一个商品也可以被分配给不同类型的条形码,如

productBarcode = .QRCode("ABCDEFGHIJKLMNOP") 但是,在任何时间只能存储其中一个,这时

原始的Barcode.UPCA和其整数相关值被新的Barcode.QRCode和其字符串相关值所替代。
像以前那样,不同的条形码类型可以使用一个 switch 语句来检查,然而这次相关值可以被提取作为 switch 语句的一部分。你可以在 的 case 分支代码中提取每个相关值作为一个常量(用 前缀)或者作为一个变量(用 前缀)来使用:
switch productBarcode {
case .UPCA(let numberSystem, let manufacturer, let product, let check):
print("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).") 
<span style="font-family: Arial, Helvetica, sans-serif;">case .QRCode(let productCode):</span>
<span style="font-family: Arial, Helvetica, sans-serif;">print("QR code: \(productCode).") }</span>
// 输出 "QR code: ABCDEFGHIJKLMNOP."


如果一个枚举成员的所有相关值被提取为常量,或者它们全部被提取为变量,为了简洁,你可以只放置一个var或者let标注在成员名称前:

switch productBarcode {
case let .UPCA(numberSystem, manufacturer, product, check):
print("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).") 
case let .QRCode(productCode):
print("QR code: \(productCode).") }
// 输出 "QR code: ABCDEFGHIJKLMNOP."


原始值Raw Values

原始值可以是字符串,字符,或者任何整型值或浮点型值。每个原始值在它的枚举声明中必须是唯一的。

注意:原始值和相关值是不相同的。当你开始在你的代码中定义枚举的时候原始值是被预先填充的值。对于一个特定的枚举成员,它的原始值始终是相同的。相关值是当你在创建一个基于枚举成员的新常量或变量时才会被设置,并且每次当你这么做得时候,它的值可以是不同的。

原始值的隐式赋值

当使用整数作为原始值时,隐式赋值的值依次递增1。如果第一个值没有被赋初值,将会被自动置为0。

当使用字符串作为枚举类型的初值时,每个枚举成员的隐式初值则为该成员的名称。


原始值初始化枚举变量

通过原始值7,从而创建枚举成员:

let possiblePlanet = Planet(rawValue: 7) // possiblePlanet 类型为 Planet? 值为 Planet.Uranus

然而,并非所有可能的 值都可以找到一个匹配的行星。正因为如此,构造函数可以返回一个可选的枚举成员。在上面的例子中, 是 类型,或“可选的 ”。

果你试图寻找一个位置为9的行星,通过参数为rawValue构造函数返回的可选Planet的值为nil

递归枚举Recursive Enumerations

递归枚举:表示它的枚举中,有一个或多个枚举成员拥有该枚举的其他成员作为相关值。使用递归枚举时,编译器会插入一个中间层。你可以在枚举成员前加上 indirect 来表示这成员可递归。 例如:下面的枚举类型存储了简单的算数表达式:

enum ArithmeticExpression{
case Number(Int)
indirect case Addition(ArithmeticExpression,ArithmeticExpression)
indirect case Multiplication(ArithmeticExpression,ArithmeticExpression)
}
也可以在枚举类型开头加上indirect来表示所有成员可递归,如

indirect enum ArithmeticExpression {}

递归函数可以很直观地使用具有递归性质的数据结构。例如,下面是一个计算算数表达式的函数:


func evaluate(expression:ArithmeticExpression) -> Int{
switch expression{
case .Number(let value):
return value
case .Addition(let left, let right):
return evaluate(left)+evaluate(right)
case .Multiplication(let left, let right):
return evaluate(left)*evaluate(right)
}
}
func objectDemoWithEnumerations(){

let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let sum = ArithmeticExpression.Addition(five, four)
let product = ArithmeticExpression.Multiplication(sum, four)
print(evaluate(product)) // 36
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: