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
复制代码

 

posted on   低头捡石頭  阅读(40)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示