Swift 学习笔记:枚举

45 阅读4分钟

Swift 的枚举(Enumerations)是一种强大的数据类型,它可以定义一组相关的值,并且可以附带任意类型的关联值。Swift 的枚举不仅可以表示简单的值,还可以定义方法和计算属性,甚至可以定义嵌套类型。

枚举的定义

在 Swift 中,我们可以使用 enum 关键字来定义一个枚举。下面是一个简单的例子:

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

这个枚举定义了一个名为 CompassPoint 的类型,它有四个可能的值:north、south、east 和 west。

枚举的使用

我们可以使用 . 来访问枚举的值:

let direction = CompassPoint.north

我们也可以使用 switch 语句来匹配枚举的值:

switch direction {
case .north:
    print("We are heading north")
case .south:
    print("We are heading south")
case .east:
    print("We are heading east")
case .west:
    print("We are heading west")
}

枚举的关联值

Swift 的枚举可以有关联值。这意味着我们可以将任意类型的数据附加到枚举的值上。例如,我们可以定义一个 Barcode 枚举,它可以是一个具有整数值的 UPC 码,也可以是一个具有字符串值的 QR 码:

enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}

然后,我们可以像这样使用它:

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

在 switch 语句中,我们可以使用模式匹配来提取关联值:

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

原始值(Raw Values)

Swift 的枚举成员可以被赋予默认的原始值。这些原始值的类型必须是相同的,例如整数、浮点数、字符串或字符。

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

在这个例子中,Planet 的原始值类型是 Int,并且 mercury 的原始值是 1。其余的枚举成员会自动递增。

隐式赋值

如果枚举的原始值类型是 Int 或 String,并且你没有为每个枚举成员提供原始值,Swift 会自动为你赋值。

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

在这个例子中,CompassPoint 的原始值类型是 String,并且每个枚举成员的原始值就是它自己的名字。

从原始值初始化

如果你定义了枚举的原始值,你可以使用原始值来创建枚举的实例。

let possiblePlanet = Planet(rawValue: 3)

在这个例子中,possiblePlanet 是 Planet? 类型,或者说“可选的 Planet”。这是因为并非所有的 Int 值都可以找到一个匹配的行星。

递归枚举

递归枚举是一种枚举类型,它的一部分枚举成员的关联值类型是枚举类型本身。在声明递归枚举时,使用 indirect 关键字。

indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}

在这个例子中,.addition 和 .multiplication 的关联值也是 ArithmeticExpression 类型 —— 这就是递归的部分。

枚举的方法

Swift 的枚举可以定义方法。这些方法可以访问枚举成员的关联值,也可以访问枚举的其他成员。

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

    func description() -> String {
        switch self {
        case .mercury:
            return "Mercury is the closest planet to the Sun."
        case .venus:
            return "Venus is the second planet from the Sun."
        case .earth:
            return "Earth is the third planet from the Sun."
        // ...其他行星
        }
    }
}

在这个例子中,Planet 枚举定义了一个 description 方法,它返回每个行星的描述。

枚举的计算属性

除了方法,Swift 的枚举还可以定义计算属性。计算属性不直接存储值,而是提供一个读取器和一个可选的设置器,来间接获取和设置其他属性或变量的值。

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

    var numberOfMoons: Int {
        switch self {
        case .earth:
            return 1
        case .mars:
            return 2
        // ...其他行星
        default:
            return 0
        }
    }
}

在这个例子中,Planet 枚举定义了一个 numberOfMoons 计算属性,它返回每个行星的卫星数量。

枚举的扩展

和其他类型一样,枚举也可以被扩展。扩展可以添加新的计算属性和方法,但不能添加存储属性或者新的案例。

extension Planet {
    var isTerrestrial: Bool {
        switch self {
        case .mercury, .venus, .earth, .mars:
            return true
        default:
            return false
        }
    }
}

在这个例子中,我们为 Planet 枚举添加了一个新的计算属性 isTerrestrial,它表示行星是否是类地行星。

总的来说,Swift 的枚举是一种非常强大的数据类型,它可以帮助我们更好地组织和表示复杂的数据结构。