枚举 #
一、枚举概述 #
枚举为一组相关值定义一个通用类型,使代码更安全、更易读。
1.1 枚举特点 #
- 值类型
- 支持关联值
- 支持原始值
- 支持方法和属性
二、基本枚举 #
2.1 定义枚举 #
swift
enum Direction {
case north
case south
case east
case west
}
enum CompassPoint {
case north, south, east, west
}
let direction = Direction.north
print(direction)
2.2 使用枚举 #
swift
var currentDirection = Direction.north
currentDirection = .south
switch currentDirection {
case .north:
print("向北")
case .south:
print("向南")
case .east:
print("向东")
case .west:
print("向西")
}
三、关联值 #
3.1 基本用法 #
swift
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
print("UPC: \(numberSystem)-\(manufacturer)-\(product)-\(check)")
case .qrCode(let productCode):
print("QR: \(productCode)")
}
3.2 提取关联值 #
swift
enum Response {
case success(Data)
case failure(Error)
}
func handle(response: Response) {
switch response {
case .success(let data):
print("成功: \(data)")
case .failure(let error):
print("失败: \(error)")
}
}
3.3 实际应用 #
swift
enum NetworkResponse {
case loading
case success(User)
case error(String)
}
func handle(response: NetworkResponse) {
switch response {
case .loading:
print("加载中...")
case .success(let user):
print("用户: \(user.name)")
case .error(let message):
print("错误: \(message)")
}
}
四、原始值 #
4.1 基本用法 #
swift
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
print(ASCIIControlCharacter.tab.rawValue)
4.2 隐式原始值 #
swift
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
print(Planet.earth.rawValue)
if let planet = Planet(rawValue: 3) {
print(planet)
}
4.3 字符串原始值 #
swift
enum Direction: String {
case north = "北"
case south = "南"
case east = "东"
case west = "西"
}
print(Direction.north.rawValue)
if let direction = Direction(rawValue: "南") {
print(direction)
}
五、递归枚举 #
5.1 indirect关键字 #
swift
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
indirect enum Expr {
case number(Int)
case add(Expr, Expr)
case multiply(Expr, Expr)
}
func evaluate(_ expression: Expr) -> Int {
switch expression {
case .number(let value):
return value
case .add(let left, let right):
return evaluate(left) + evaluate(right)
case .multiply(let left, let right):
return evaluate(left) * evaluate(right)
}
}
let expr = Expr.multiply(
Expr.add(Expr.number(2), Expr.number(3)),
Expr.number(4)
)
print(evaluate(expr))
六、枚举方法和属性 #
6.1 方法 #
swift
enum Direction {
case north, south, east, west
func opposite() -> Direction {
switch self {
case .north: return .south
case .south: return .north
case .east: return .west
case .west: return .east
}
}
mutating func turnRight() {
switch self {
case .north: self = .east
case .south: self = .west
case .east: self = .south
case .west: self = .north
}
}
}
var direction = Direction.north
print(direction.opposite())
direction.turnRight()
print(direction)
6.2 计算属性 #
swift
enum Season {
case spring, summer, autumn, winter
var months: [String] {
switch self {
case .spring: return ["3月", "4月", "5月"]
case .summer: return ["6月", "7月", "8月"]
case .autumn: return ["9月", "10月", "11月"]
case .winter: return ["12月", "1月", "2月"]
}
}
var temperature: String {
switch self {
case .spring: return "温暖"
case .summer: return "炎热"
case .autumn: return "凉爽"
case .winter: return "寒冷"
}
}
}
print(Season.summer.months)
print(Season.winter.temperature)
七、协议遵循 #
7.1 遵循协议 #
swift
enum Direction: CaseIterable {
case north, south, east, west
}
print(Direction.allCases.count)
for direction in Direction.allCases {
print(direction)
}
7.2 Codable #
swift
enum Status: String, Codable {
case pending = "pending"
case approved = "approved"
case rejected = "rejected"
}
struct Task: Codable {
let id: Int
let status: Status
}
let json = """
{"id": 1, "status": "approved"}
"""
let task = try JSONDecoder().decode(Task.self, from: json.data(using: .utf8)!)
print(task.status)
八、实际应用 #
8.1 状态机 #
swift
enum LoadingState {
case idle
case loading
case loaded(Data)
case error(Error)
var isLoading: Bool {
if case .loading = self { return true }
return false
}
var data: Data? {
if case .loaded(let data) = self { return data }
return nil
}
}
class ViewModel {
var state: LoadingState = .idle
func load() {
state = .loading
DispatchQueue.global().async {
Thread.sleep(forTimeInterval: 1)
DispatchQueue.main.async {
self.state = .loaded(Data())
}
}
}
}
8.2 结果类型 #
swift
enum Result<Success, Failure: Error> {
case success(Success)
case failure(Failure)
func map<T>(_ transform: (Success) -> T) -> Result<T, Failure> {
switch self {
case .success(let value):
return .success(transform(value))
case .failure(let error):
return .failure(error)
}
}
func get() throws -> Success {
switch self {
case .success(let value):
return value
case .failure(let error):
throw error
}
}
}
8.3 配置类型 #
swift
enum Environment {
case development
case staging
case production
var baseURL: String {
switch self {
case .development:
return "http://localhost:3000"
case .staging:
return "https://staging.api.example.com"
case .production:
return "https://api.example.com"
}
}
var apiKey: String {
switch self {
case .development:
return "dev_key"
case .staging:
return "staging_key"
case .production:
return "prod_key"
}
}
}
九、总结 #
本章学习了Swift枚举:
- 基本枚举:定义和使用
- 关联值:存储额外信息
- 原始值:预定义值
- 递归枚举:嵌套结构
最佳实践:
- 使用枚举表示有限状态
- 使用关联值携带数据
- 遵循协议增加功能
- 配合switch使用
下一章,我们将学习结构体!
最后更新:2026-03-26