美文网首页
swift中的枚举

swift中的枚举

作者: Taureau_2d81 | 来源:发表于2017-06-16 14:03 被阅读0次

    枚举语法

    enum CompassPoint {

    case north

    case south

    case east

    case west

    }

    多个成员值可以出现在同一行上,用逗号隔开:

    enum Planet {

    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune

    }

    使用 Switch 语句匹配枚举值

    你可以使用switch语句匹配单个枚举值:

    directionToHead = .south

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

    case .west:

    print("Where the skies are blue")

    }

    // 打印 "Watch out for penguins”

    关联值

    枚举成员可以指定任意类型的关联值存储到枚举成员中,就像其他语言中的联合体(unions)和变体(variants)。你可以在一个枚举中定义一组相关的枚举成员,每一个枚举成员都可以有适当类型的关联值。

    如商品上有条码与二维码,

    这便于库存跟踪系统用包含四个整型值的元组存储 UPC 码,以及用任意长度的字符串储存 QR 码。

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

    enum Barcode {

    case upc(Int, Int, Int, Int)

    case qrCode(String)

    }

    以上代码可以这么理解:

    “定义一个名为Barcode的枚举类型,它的一个成员值是具有(Int,Int,Int,Int)类型关联值的upc,另一个成员值是具有String类型关联值的qrCode。”

    这个定义不提供任何Int或String类型的关联值,它只是定义了,当Barcode常量和变量等于Barcode.upc或Barcode.qrCode时,可以存储的关联值的类型。

    然后可以使用任意一种条形码类型创建新的条形码,例如:

    var productBarcode = Barcode.upc(8, 85909, 51226, 3)

    上面的例子创建了一个名为productBarcode的变量,并将Barcode.upc赋值给它,关联的元组值为(8, 85909, 51226, 3)。

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

    productBarcode = .qrCode("ABCDEFGHIJKLMNOP")

    这时,原始的Barcode.upc和其整数关联值被新的Barcode.qrCode和其字符串关联值所替代。Barcode类型的常量和变量可以存储一个.upc或者一个.qrCode(连同它们的关联值),但是在同一时间只能存储这两个值中的一个。

    像先前那样,可以使用一个 switch 语句来检查不同的条形码类型。然而,这一次,关联值可以被提取出来作为 switch 语句的一部分。你可以在switch的 case 分支代码中提取每个关联值作为一个常量(用let前缀)或者作为一个变量(用var前缀)来使用:

    switch productBarcode {

    case .upc(let numberSystem, let manufacturer, let product, let check):

    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")

    case .qrCode(let productCode):

    print("QR code: \(productCode).")

    }

    // 打印 "QR code: ABCDEFGHIJKLMNOP."

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

    switch productBarcode {

    case let .upc(numberSystem, manufacturer, product, check):

    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")

    case let .qrCode(productCode):

    print("QR code: \(productCode).")

    }

    // 输出 "QR code: ABCDEFGHIJKLMNOP."

    原始值

    在关联值小节的条形码例子中,演示了如何声明存储不同类型关联值的枚举成员。作为关联值的替代选择,枚举成员可以被默认值(称为  原始值  )预填充,这些原始值的类型必须相同。

    这是一个使用 ASCII 码作为原始值的枚举:

    enum ASCIIControlCharacter: Character {

    case tab = "\t"

    case lineFeed = "\n"

    case carriageReturn = "\r"

    }

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

    注意

    原始值和关联值是不同的。原始值是在定义枚举时被预先填充的值,像上述三个 ASCII 码。对于一个特定的枚举成员,它的原始值始终不变。关联值是创建一个基于枚举成员的常量或变量时才设置的值,枚举成员的关联值可以变化。

    原始值的隐式赋值

    在使用原始值为整数或者字符串类型的枚举时,不需要显式地为每一个枚举成员设置原始值,Swift 将会自动为你赋值。

    例如,当使用整数作为原始值时,隐式赋值的值依次递增1。如果第一个枚举成员没有设置原始值,其原始值将为0。

    下面的枚举是对之前Planet这个枚举的一个细化,利用整型的原始值来表示每个行星在太阳系中的顺序:

    enum Planet: Int {

    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune

    }

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

    下面的例子是CompassPoint枚举的细化,使用字符串类型的原始值来表示各个方向的名称:

    enum CompassPoint: String {

    case north, south, east, west

    }

    使用枚举成员的rawValue属性可以访问该枚举成员的原始值:

    let earthsOrder = Planet.earth.rawValue

    // earthsOrder 值为 3

    let sunsetDirection = CompassPoint.west.rawValue

    // sunsetDirection 值为 "west"

    rawValue还有另外一种用法,你可以使用这个初始化方法来创建一个新的枚举实例。

    let possiblePlanet = Planet(rawValue: 7)

    // possiblePlanet 类型为 Planet? 值为 Planet.uranus

    递归枚举

    递归枚举是一种枚举类型,它有一个或多个枚举成员使用该枚举类型的实例作为关联值。使用递归枚举时,编译器会插入一个间接层。你可以在枚举成员前加上indirect来表示该成员可递归。

    例如,下面的例子中,枚举类型存储了简单的算术表达式:

    enum ArithmeticExpression {

    case number(Int)

    indirect case addition(ArithmeticExpression, ArithmeticExpression)

    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)

    }

    你也可以在枚举类型开头加上indirect关键字来表明它的所有成员都是可递归的:

    indirect enum ArithmeticExpression {

    case number(Int)

    case addition(ArithmeticExpression, ArithmeticExpression)

    case multiplication(ArithmeticExpression, ArithmeticExpression)

    }

    let five = ArithmeticExpression.number(5)

    let four = ArithmeticExpression.number(4)

    let sum = ArithmeticExpression.addition(five, four)

    let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

    要操作具有递归性质的数据结构,使用递归函数是一种直截了当的方式。例如,下面是一个对算术表达式求值的函数:

    func evaluate(_ expression: ArithmeticExpression) -> Int {

    switch expression {

    case let .number(value):

    return value

    case let .addition(left, right):

    return evaluate(left) + evaluate(right)

    case let .multiplication(left, right):

    return evaluate(left) * evaluate(right)

    }

    }

    print(evaluate(product))

    // 打印 "18"

    该函数如果遇到纯数字,就直接返回该数字的值。如果遇到的是加法或乘法运算,则分别计算左边表达式和右边表达式的值,然后相加或相乘。

    相关文章

      网友评论

          本文标题:swift中的枚举

          本文链接:https://www.haomeiwen.com/subject/xtwpqxtx.html