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 的枚举是一种非常强大的数据类型,它可以帮助我们更好地组织和表示复杂的数据结构。