枚举—Swift学习笔记(十一)

注:本文为自己学习The Swift Programming Language的笔记,其中的例子为引用原书和其他博文或自己原创的。每个例子都会批注一些实践过程中的经验或思考总结。

1.基础

枚举类型定义了一组通用类型的相关联的值,它提供一种类型安全的方式来使用这些值。

Swift的美剧类型比C语言的枚举类型更加灵活,它并不需要为每个枚举成员赋一个值;如果赋了值,这个值可以是字符串、字符以及整数和浮点数的任何类型,它被称作原始值[raw value]。

除此之外,枚举成员可以可以制定任何类型的相关值储存在不同的成员值中,很像其他语言的联合体[Union]和变体[Variant]。你可以定义一组通用的相关成员作为枚举的一部分,每一组都有不同的一组与它相关的适当类型的数值。

Swift的枚举类型是一等类型(此外类和结构体也属于一等类型),它们采用了很多传统上只被类所支持的特征,比如说计算属性(用于提供关于枚举当前值的附加信息)、实例方法(用于提供和枚举所代表的值相关联的功能)。

枚举也可以定义构造函数来提供一个初始成员值,可以被扩展,可以遵守协议来提供标准的功能。

2.枚举语法

枚举用enum关键字来声明,与C语言不同的是每一个枚举成员需要用case关键字引出:

enum CompassPoint {
    case North
    case South
    case East
    case West
}
不像类C语言,Swift的枚举成员在创建时是没有整型默认值的。比如上例中North并不隐式的等于0。不同的枚举成员可以显式定义不同类型。

不同的枚举成员可以写在同一个case中:

enum Planet {
    case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
Swift中每个枚举类型,比如CompassPoint或者Planet都是一个全新的类型,它的首字母应该写成大写而且是单数形式。

用点运算符引出枚举成员,一旦一个变量被声明为某种枚举类型变量,那么可以省略枚举名字直接用点符号和枚举成员赋值:

var direction = CompassPoint.North
direction = .South
3.switch语句匹配枚举值

我们常用case来判断枚举变量的值,然后做出相应的响应:

direction = .South
switch direction {
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
由于类型推断case中枚举类型可以省略,并且由于switch语句要求完全枚举,因此若不将枚举成员一一列举就要加上default语句。

4.关联值

有时候把一些和枚举成员相关联的不同类型的值储存在枚举成员后面会很有用,它能配合枚举成员存储额外的信息。

Swift的关联值[Associated Values]可以是任意的已知类型,每个枚举成员也可以有不同类型的关联值。

用原书中比较形象的例子来说明关联值的使用方法。

库存追踪系统需要追踪两种不同类型的条码。比如一维条码(条形码),有些产品使用UPC-A格式的条形码,它使用0-9的数字,首位为数字系统编码,中间10位为标识号码,最后一位是检查是否正确扫描的检错码。而有些产品又使用二位条码(二维码),QR格式的二维码可以使用任意的ISO 8859-1字符,并且能被最多2953个字符的字符串编码。所以表示一个库存追踪系统最方便的形式是在UPCA条码后添加三元Int元组关联值和在QRCode条码后添加String类型关联值:

enum Barcode {
    case UPCA(Int, Int, Int)
    case QRCode(String)
}
枚举成员定义时不给出关联值具体值,而是在定义枚举类型常量或变量是给出,它表示该枚举成员的额外信息:

var productBarcode = Barcode.UPCA(8, 85909_51226, 3)
在匹配含有关联值的枚举变量或常量是可以使用case值绑定的形式的switch:

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可以提出括号书写,上面的代码等价于:

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).")
}

5.原始值

另一种不同于关联值方式的反映额外信息的方式是给枚举成员赋予一个默认值,在Swift中被称为原始值[Raw Value]。
原始值的类型可以是字符、字符串、任意整型或者任意浮点数类型,同一个枚举类型应该是同一的类型的,需要用类型注释在枚举类型名字后面指出。
若使用整型原始值编译器默认以增量的形式给没有显式声明原始值的赋予原始值:
enum PlanetWithRawValue : Int {
    case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
上例中,自动原始值让PlanetWithRawValue.Earth = 3。
有原始值的枚举类型有两个默认的方法toRaw和fromRaw,从字面意思就可以看出,toRaw将枚举成员转换为原始值,它没有传入参数,返回值是一个RawType的原始值;fromRaw方法有一个RawType类型的参数,返回值是一个可空的枚举类型(其原因学过可空类型后应该很清楚,因为传入的原始值可能非法,它并不对应任何枚举成员)。













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值