Swift - 枚举
前言
1 - Swift 中的枚举更加灵活!假定给枚举成员提供一个值(原始值),则该值的类型可以是字符串、字符、整型、浮点数
2 - 枚举成员可以指定任意类型的关联值存储到枚举成员中,就像其他语言中的联合体和变体。Swift 中枚举类型是一等类型
3 - 计算属性用于提供枚举值的附加信息;实例方法用于提供和枚举值相关联的功能
4 - 枚举也可以定义构造函数来提供一个初始值;可以在原始实现的基础上扩展它们的功能;还可以遵循协议来提供标准的功能
枚举
1 - Swift 和 C、Objective-C 不同,它枚举成员在被创建时不会被赋予一个默认的整型值
1 enum CompassPoint { 2 3 // 使用 case 关键字来定义枚举成员 4 case north 5 case south 6 case east 7 case west 8 } 9 10 // 多个成员值可以出现在同一行上,用逗号隔开 11 enum Planet { 12 case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune 13 } 14 15 // 赋值 16 // 方式一:标准 17 var directionToHead = CompassPoint.west 18 // 方式二:更为简短 19 directionToHead = .east 20 directionToHead = .south 21 22 switch directionToHead { 23 24 case.north: 25 print("Lots of planets have a north") 26 case.south: 27 print("Watch out for penguins") // 执行该分支 28 case.east: 29 print("Where the sun rises") 30 case.west: 31 print("Where the skies are blue") 32 } 33 34 35 // 使用 default 分支来涵盖所有未明确处理的枚举成员 36 let somePlanet = Planet.mercury 37 switch somePlanet { 38 case.earth: 39 print("Mostly harmless") 40 default: 41 print("Not a safe place for humans") // 执行该分支 42 } 43 44 // CaseIterable 协议:使我们可以访问 allCases 45 // 遍历成员:allCases 46 enum Beverage: CaseIterable { 47 case coffee, tea, juice 48 } 49 50 let numberOfChoices = Beverage.allCases.count 51 print("\(numberOfChoices) beverages available") 52 // 3 beverages available 53 for beverage in Beverage.allCases { 54 print(beverage) 55 } 56 // coffee 57 // tea 58 // juice
2 - 关联值
1 // 关联值 2 enum Barcode { 3 case upc(Int, Int, Int, Int) 4 case qrCode(String) 5 } 6 7 // 赋值 8 var productBarcode = Barcode.upc(8, 85909, 51226, 3) // 元组 9 productBarcode = Barcode.qrCode("ABCDEFGHIJKLMNOP") // 字符串 10 11 // 值绑定 12 switch productBarcode { 13 14 case.upc(let numberSystem, let manufacturer, let product, let check): 15 print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).") 16 case.qrCode(let productCode): 17 print("QR code: \(productCode)") // 执行该分支 18 } 19 20 // 可以只在成员名称前标注一个 let 或 var,前提是一个枚举成员的所有关联值均是常量或变量 21 switch productBarcode { 22 case let.upc(numberSystem, manufacturer, product, check): 23 print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).") 24 case let.qrCode(productCode): 25 print("QR code: \(productCode).") 26 }
3 - 原始值
1 // 枚举成员可以被默认值(原始值)预填充,其类型必须相同 2 // ASCIIControlCharacter 的原始值类型被定义为 Character 3 enum ASCIIControlCharacter: Character { 4 case tab = "\t" 5 case lineFeed = "\n" 6 case carriageReturn = "\r" 7 } 8 9 // 原始值的隐式赋值 10 // 在使用原始值为整数或者字符串类型的枚举时,不需要显式地为每一个枚举成员设置原始值 11 enum PlanetNum2: Int { 12 13 // PlanetNum2.mercury 的显式原始值为 1 14 // PlanetNum2.venus 的隐式原始值为 2 15 // 依次类推 16 case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune 17 } 18 19 // 当使用字符串作为枚举类型的原始值时,每个枚举成员的隐式原始值为该枚举成员的名称 20 // 比如 CompassPointNum2.south 拥有隐式原始值 south 21 enum CompassPointNum2: String { 22 case north, south, east, west 23 } 24 25 // rawValue 属性:访问该枚举成员的原始值 26 let earthsOrder = PlanetNum2.earth.rawValue // 3 27 let sunsetDirection = CompassPointNum2.west.rawValue // west 28 29 30 // 使用原始值初始化枚举实例 31 let possiblePlanet = PlanetNum2(rawValue: 7) 32 // possiblePlanet 类型是可选类型 33 print(possiblePlanet!) // uranus 34 35 // 不存在的情况 36 let positionToFind = 11 37 print(PlanetNum2(rawValue: positionToFind) as Any) // nil 38 39 // if 语句创建了一个可选 PlanetNum2 40 if let somePlanet = PlanetNum2(rawValue: 3) { 41 42 switch somePlanet { 43 case.earth: 44 print("Mostly harmless") // 执行该语句 45 default: 46 print("Not a safe place for humans") 47 } 48 } else { 49 print("There isn't a planet at position \(positionToFind)") 50 }
注:原始值和关联值是不同的。原始值是在定义枚举时被预先填充的值,对于一个特定的枚举成员,它的原始值始终不变;关联值是创建一个基于枚举成员的常量或变量时才设置的值,枚举成员的关联值可以变化
4 - 递归枚举:它有一个或多个枚举成员使用该枚举类型的实例作为关联值。使用递归枚举时编译器会插入一个间接层,你可以在枚举成员前加上 indirect 来表示该成员可递归
1 // 方式一 2 enum ArithmeticExpression01 { 3 // 纯数字 4 case number(Int) 5 // 相加 6 indirect case addition(ArithmeticExpression01, ArithmeticExpression01) 7 // 相减 8 indirect case multiplication(ArithmeticExpression01, ArithmeticExpression01) 9 } 10 11 12 // 方式二:在枚举类型开头加上 indirect 关键字来表明它的所有成员都是可递归的 13 indirect enum ArithmeticExpression02 { 14 case number(Int) 15 case addition(ArithmeticExpression02, ArithmeticExpression02) 16 case multiplication(ArithmeticExpression02, ArithmeticExpression02) 17 } 18 19 // (5 + 4) * 2 20 let five = ArithmeticExpression01.number(5) 21 let four = ArithmeticExpression01.number(4) 22 let product = ArithmeticExpression01.multiplication(ArithmeticExpression01.addition(five, four), ArithmeticExpression01.number(2)) 23 24 25 // 要操作具有递归性质的数据结构 26 func evaluate(_ expression: ArithmeticExpression01) -> Int { 27 28 switch expression { 29 30 // 如果是纯数字,就直接返回该数字的值 31 case let.number(value): 32 return value 33 case let.addition(left, right): 34 return evaluate(left) + evaluate(right) 35 case let.multiplication(left, right): 36 return evaluate(left) * evaluate(right) 37 } 38 } 39 print(evaluate(product)) // 18
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了