Swift枚举Enumerations

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

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

枚举语法

枚举使用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)

但是通过原始值获取枚举时,有的时候获取不到,会返回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

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...