04-枚举
程序员文章站
2024-03-23 10:01:52
...
enum Direction {
case north
case south
case east
case west
}
enum Direction {
case north, south, east, west
}
var dir = Direction.west
dir = Direction.east
dir = .north
print(dir) // north
switch dir {
case .north:
print("north")
case .south:
print("south")
case .east:
print("east")
case .west:
print("west")
}
有时将枚举的成员值跟其他类型的值关联存储在一起, 会非常有用
enum Score {
case points(Int)
case grade(Character)
}
var score = Score.points(96)
score = .grade("A")
switch score {
case let .points(i):
print(i, "points")
case let .grade(i):
print("grade", i)
}
// 打印结果:grade A。
// 注意:其实 i 就是 字符串 "A",'let .grade(i)'相当于拿到枚举中 grade 这个成员值与它关联的值 'A'
enum Date {
case digit(year: Int, month: Int, day: Int)
case string(String)
}
var date = Date.digit(year: 2020, month: 6, day: 4)
date = Date.string("2020-6-4")
switch date {
case .digit(let year, let month, let day):
print("\(year)-\(month)-\(day)")
case let .string(vaule):
print(vaule)
}
enum Password {
case number(Int, Int, Int, Int)
case gesture(String)
}
var pwd = Password.number(3, 5, 7, 8)
pwd = .gesture("12369")
switch pwd {
case .number(let n1, let n2, let n3, let n4):
print(n1, n2, n3, n4)
case let .gesture(vaule):
print(vaule)
}
枚举成员可以使用相同类型的默认值预先对应,这个默认值叫做:原始值。
enum PokerSuit: Character {
case spade = "♠️"
case heart = "❤️"
case diamond = "♦️"
case club = "♣️"
}
var suit = PokerSuit.spade
print(suit) // spade
print(suit.rawValue) // ♠️
print(PokerSuit.club.rawValue) // ♣️
enum Grade: String {
case perfect = "A"
case great = "B"
case good = "C"
case bad = "D"
}
print(Grade.perfect.rawValue) // A
print(Grade.great.rawValue) // B
print(Grade.good.rawValue) // C
print(Grade.bad.rawValue) // D
注意:原始值不占用枚举变量的内存
如果枚举的原始值类型是 Int, String 类型,Swift 会自动分配原始值
enum Direction: String {
case north = "north"
case south = "south"
case east = "east"
case west = "west"
}
上面这种写法等价于下面这种写法
enum Direction: String {
case north, south, east, west
}
print(Direction.north) // north
print(Direction.north.rawValue) // north
- Int 类型的枚举,如果不去指定枚举中某个成员的原始值,它的原始值从 0 开始依次往上增加
enum Season: Int {
case spring, summer, autumn, winter
}
print(Season.spring.rawValue) // 0
print(Season.summer.rawValue) // 1
print(Season.autumn.rawValue) // 2
print(Season.winter.rawValue) // 3
- Int 类型的枚举,如果指定枚举中某个成员的原始值,它的原始值就会从指定的值开始依次往上增加,如果后面再有指定成员的原始值是某个值,它又会从指定的值开始依次往上增加
enum Season: Int {
case spring = 1, summer, autumn = 4, winter
}
print(Season.spring.rawValue) // 1
print(Season.summer.rawValue) // 2
print(Season.autumn.rawValue) // 4
print(Season.winter.rawValue) // 5
注意:枚举中的原始值不能有重复的,否则会报错
indirect enum ArithExpr {
case number(Int)
case sum(ArithExpr, ArithExpr)
case difference(ArithExpr, ArithExpr)
}
下面这些写法等价于上面这种写法
enum ArithExpr {
case number(Int)
indirect case sum(ArithExpr, ArithExpr)
indirect case difference(ArithExpr, ArithExpr)
}
let five = ArithExpr.number(5)
let four = ArithExpr.number(4)
let tow = ArithExpr.number(2)
let sum = ArithExpr.sum(five, four)
let difference = ArithExpr.difference(sum, tow)
func calculate(_ expr: ArithExpr) -> Int {
switch expr {
case let .number(vaule):
return vaule
case let .sum(left, right):
return calculate(left) + calculate(right)
case let .difference(left, right):
return calculate(left) - calculate(right)
}
}
print(calculate(difference)) // 7
可以使用MemoryLayout 获取数据类型占用内存的大小
enum Password {
case number(Int, Int, Int, Int)
case other
}
MemoryLayout<Password>.stride // 40 分配占用空间的大小
MemoryLayout<Password>.size // 33 占用空间的大小
MemoryLayout<Password>.alignment // 8 内存对齐
在 Password 枚举中,number 在 64 位系统下占用 32 个字节(因为 Int 类型在 64 位系统下占用 8 个字节),other 占用 1 个字节。所以 Password 这个枚举共占用 33 个字节,由于内存对齐是 8 个字节,所以系统会分配 40 个字节的空间给 Password 存,但实际上 Password 只用 33 个字节就够了。
var pwd = Password.number(9, 8, 6, 4)
pwd = .other
MemoryLayout.stride(ofValue: pwd) // 40
MemoryLayout.size(ofValue: pwd) // 33
MemoryLayout.alignment(ofValue: pwd) // 8
本文章只是本人的学习笔记!
下一篇: 01-基础语法