Swift08:枚举

148 阅读3分钟

回顾一下OC中的枚举使用:

typedef enum _CompassPoint {
    North = 0,
    South,
    East,
    West
} CompassPoint;

Swift 中的枚举

在 Swift 中,枚举类型是一等(first-class)类型。它们采用了很多在传统上只被类(class)所支持的特性,例如:

  • 计算属性(computed properties),用于提供枚举值的附加信息;
  • 实例方法(instance methods),用于提供和枚举值相关联的功能;
  • 定义构造函数(initializers)来提供一个初始值;
  • 扩展,可以在原始实现的基础上扩展它们的功能;
  • 遵循协议(protocols)来提供标准的功能;

枚举定义

enum CompassPoint {
    case north
    case south
    case east
    case west
}

enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

Swift 的枚举成员在被创建时不会被赋予一个默认的整型值。

枚举赋值

var directionToHead = CompassPoint.west

directionToHead = .east // 简写形式

枚举的遍历

enum Beverage: CaseIterable {  // 遵循 CaseIterable 协议,即可遍历
    case coffee, tea, juice
}
let numberOfChoices = Beverage.allCases.count
print("\(numberOfChoices) beverages available") // 打印“3 beverages available”
for beverage in Beverage.allCases {
    print(beverage)
}
// coffee
// tea
// juice

关联值

枚举成员可以指定任意类型的关联值存储到枚举成员。 示例:

// 条形码 类型
enum Barcode {
    case upc(Int, Int, Int, Int) // 一维条形码 实例,关联元组类型
    case qrCode(String) // 二维码 实例,关联字符串
}

对于枚举的理解

枚举:类型,比如 条形码

枚举成员:类型对应的实例,比如 一维码、二维码

枚举实例赋值

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

枚举匹配写法一:

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.”

枚举匹配写法二:

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.”

原始值

如果给枚举成员提供一个值(称为原始值),则该值的类型可以是字符串字符,或是一个整型值或浮点数。 作为关联值的替代选择,枚举成员可以被默认值(称为原始值)预填充,这些原始值的类型必须相同

示例:枚举类型 ASCIIControlCharacter 的原始值类型被定义为 Character

enum ASCIIControlCharacter: Character {
    case tab = "\t"
    case lineFeed = "\n"
    case carriageReturn = "\r"
}

原始值的隐式赋值

enum Planet: Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}

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

enum CompassPoint: String {
    case north, south, east, west
}

north的对应的原始值 “north”

使用原始值初始化枚举实例

let possiblePlanet = Planet(rawValue: 7) // possiblePlanet 类型为 Planet? 值为 Planet.uranus

原始值构造器是一个可失败构造器

let positionToFind = 11
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)")
}
// 打印“There isn't a planet at position 11”

关联值和原始值的区别: 对于一个特定的枚举成员,它的原始值始终不变。关联值是创建一个基于枚举成员的常量或变量时才设置的值,枚举成员的关联值可以变化。