枚举是一组相关的值的集合,并允许你在代码中使用。
枚举允许所有的值是相同类型的,也可以是不同类型的,还可以为这些值设置默认值。
枚举语法
枚举使用enum做为关键字,后跟枚举名,其内部值在一个{}内。
空枚举:
enum SomeEnumeration {
// enumeration definition goes here
}
下面这个枚举包含四个值:
// 枚举基本类型
enum CompassPoint {
case North
case South
case East
case West
}
如果你觉得case的行数太多,枚举还支持简写,将其写在一行。
enum Planet {
case Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune
}
枚举是一个崭新的类型,你可以通过let或var去获得它们。
// 使用
var directionToHead = CompassPoint.West
如果你觉得写枚举名太麻烦,枚举还支持不写枚举名,直接使用点语法。
directionToHead = .East
枚举匹配
你可以使用switch或if做枚举匹配。
var directionToHead = CompassPoint.South
// if匹配
if directionToHead == CompassPoint.South {
directionToHead = .East
}
// switch匹配
switch directionToHead {
case .North:
print("Lots of planets have a north")
case .South:
print("Watch out for penguins")
case .East:
print("Where the sun rises")
default:
print("default")
}
关联值
枚举支持关联值,在case后可以使用一个结构体。
enum Barcode {
case UPCA(Int,Int,Int)
case QRCode(String)
}
初始化
var productBarcode = Barcode.UPCA(8,85909,51226,3)
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")
使用switch做匹配,这里用到了let
switch productBarcode {
case .UPCA(let numberSystem,let manufacturer,let product,let check):
print("UPC-A: \(numberSystem),\(manufacturer),\(product),\(check).")
case .QRCode(let productCode):
print("QR code: \(productCode).")
}
如果你觉得let太麻烦了,枚举的关联值匹配也支持不写let。
switch productBarcode {
case let .UPCA(numberSystem,manufacturer,product,check):
print("UPC-A: \(numberSystem),\(check).")
case let .QRCode(productCode):
print("QR code: \(productCode).")
}
原始值
枚举支持为每个属性设置原始值,下面设置Character类型的原始值。
enum ASCIIControlCharacter: Character {
case Tab = "\t"
case LineFeed = "\n"
case CarriageReturn = "\r"
}
隐式分配原始值
enum Planet: Int {
case Mercury = 1,Neptune
}
在上面的例子中,整个枚举Planet为Int类型,并设置了Mercury=1。swift会自动为接下来的属性赋值Venus=2、Earth=3。。。
还有一种情况,你不给任何属性赋初始值,只是指定了枚举的类型。Swift也可以自动判断内部属性的原始值。
enum CompassPoint: String {
case North,South,East,West
}
如上所示,枚举会使North=”North”、South=“South”、East = “East”和West=“West”。
关于有原始值的枚举使用如下:
print("\(Planet.Earth.rawValue)") // 3
print("\(CompassPoint.West.rawValue)") // "West"
通过原始值初始化
如同初始化类,你也可以通过原始值获取枚举。
let possiblePlanet = Planet(rawValue: 7)
let positionToFind = 9
// 当原始值不匹配时,返回为nil
if let somePlanet = Planet(rawValue: positionToFind) {
switch somePlanet {
case .Earth:
print("Mostly harmless")
default:
print("Not a safe place for humans")
}
} else {
print("There isn't a planet at position \(positionToFind)")
}
循环枚举
在枚举中可以设置任何原始值,同样可以设置枚举,并且是当前枚举,需要用到的关键字是indirect。
enum ArithmeticExpression {
case Number(Int)
indirect case Addition(ArithmeticExpression,ArithmeticExpression)
indirect case Multiplication(ArithmeticExpression,ArithmeticExpression)
}
如果你觉得每个case都写indirect太麻烦,枚举还支持你将indirect写到enum前。
indirect enum ArithmeticExpression {
case Number(Int)
case Addition(ArithmeticExpression,ArithmeticExpression)
case Multiplication(ArithmeticExpression,ArithmeticExpression)
}
下面介绍了怎么运用上面的循环枚举计算(5 + 4) * 2
// 函数使用
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)
}
}
// evaluate (5 + 4) * 2
let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let sum = ArithmeticExpression.Addition(five,four)
let product = ArithmeticExpression.Multiplication(sum,ArithmeticExpression.Number(2))
print(evaluate(product))
其他
参考资料
The Swift Programming Language (Swift 2.1)
文档修改记录
时间 | 描述 |
---|---|
2015-10-28 | 根据 The Swift Programming Language (Swift 2.1)中的Enumerations总结 |