牛骨文教育服务平台(让学习变的简单)

枚举是一组相关的值的集合,并允许你在代码中使用。

枚举允许所有的值是相同类型的,也可以是不同类型的,还可以为这些值设置默认值。

枚举语法

枚举使用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, 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), (manufacturer), (product), (check).")
case let .QRCode(productCode):
    print("QR code: (productCode).")
}

原始值

枚举支持为每个属性设置原始值,下面设置Character类型的原始值。

enum ASCIIControlCharacter: Character {
    case Tab = "	"
    case LineFeed = "
"
    case CarriageReturn = "
"
}

隐式分配原始值

在枚举中,还支持隐式分配枚举值。

enum Planet: Int {
    case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, 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)

但是通过原始值获取枚举时,有的时候获取不到,会返回nil。

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总结

版权所有:http://blog.csdn.net/y550918116j