枚举概述
- 成员值: 一般只占用枚举内存最后一个字节
- 关联值:枚举内存最大占用者
- 原始值:若果枚举原始值类型是
Int
String
枚举会自动将成员赋值与成员变量相同的原始值.
关联值占用枚举内存,原始值不会占用枚举内存.如果真的想获取枚举的原始值,可使用rowValue
方法来获取.原始值是预先关联的,之后不能在修改,只能获取.因为原始值是不变的,所以没必要占用枚举内存.
枚举的基本用法
enum Direction {
case north,south,east,west
}
enum Direction {
case north
case south
case east
case west
}
//以上两种写法完全等价
var dir = Direction.west
dir = Direction.south
dir = .east
switch dir {
case .north:
print("north")
case .south:
print("south")
case .west:
print("west")
case .east:
print("east")
}
枚举关联值(Associated Values)
- 有时会将枚举的成员值跟其他类型的关联存储在一起,会非常有用
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)
}
enum Date {
case digit(year: Int ,month: Int ,day: Int)
case string(String)
}
var date = Date.digit(year: 2011, month: 9, day: 10)
date = .string("2011-09-10")
switch date {
case .digit(var year, month: let month, day: let day):
if year == 2018 {
year += 1
}
print(year,month,day)
case let .string(value):
print(value)
}
关联值举例
enum Password {
case number(Int, Int, Int, Int)
case gesture(String)
}
var pwd = Password.number(3, 1, 2, 0)
pwd = .gesture("221323")
switch pwd {
case let .number(n1, n2, n3, n4):
print("number is",n1,n2,n3,n4)
case let .gesture(str):
print("gesture is",str)
}
原始值(Raw Values)
- 枚举成员可以使用
相同类型
的默认值预先关联,这个默认值叫做:原始值
enum PokerSuit: Character {
case smile = "😀"
case laugh = "😄"
case cry = "😂"
case other = "😍"
}
var suit = PokerSuit.smile
print(suit)
print(suit.rawValue)
print(PokerSuit.cry.rawValue)
image.png
隐式原始值(Implicity Assigned Raw Values)
- 如果枚举的原始值类型是
Int
String
,Swift会自动分配原始值
enum Direction : String{
case north,south,east,west
}
print(Direction.north)//north
print(Direction.north.rawValue)//north
enum Season : Int{
case spring,summer,autumn,winter
}
print(Season.spring)//spring
print(Season.summer)//summer
print(Season.autumn)//autumn
print(Season.winter)//winter
print(Season.spring.rawValue)//0
print(Season.summer.rawValue)//1
print(Season.autumn.rawValue)//2
print(Season.winter.rawValue)//3
enum Season : Int{
case spring = 1,summer,autumn = 5,winter
}
print(Season.spring.rawValue)//1
print(Season.summer.rawValue)//2
print(Season.autumn.rawValue)//5
print(Season.winter.rawValue)//6
- 注意要预先指定
原始值
类型,才有rawValue
属性
递归枚举(Recursive Enumeration)
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 two = ArithExpr.number(2)
let sum = ArithExpr.sum(five, four)
let diff = ArithExpr.difference(sum,two)
func calculate(_ expr: ArithExpr) -> Int {
switch expr {
case let .number(value):
return value
case .sum(let left , let right):// 5 + 4 = 9
return calculate(left) + calculate(right)
case let .difference(left, right):// 9 - 2
return calculate(left) - calculate(right)
}
}
calculate(diff)// 9 - 2 = 7
MemoryLayout
- 可以使用
MemoryLayout
获取数据类型占用的内存大小
enum Password {
case none//1
case number(Int, Int, Int, Int)//32
case gesture(String)//16
case otherPassword//1
}
MemoryLayout<Password>.stride//40 系统分配的空间
MemoryLayout<Password>.size//33 实际占用的空间
MemoryLayout<Password>.alignment//8 对齐参数
enum Password {
case none//1
// case number(Int, Int, Int, Int)//32
case gesture(String)//16
case otherPassword//1
}
MemoryLayout<Password>.stride//16 系统分配的空间
MemoryLayout<Password>.size//16 实际占用的空间
MemoryLayout<Password>.alignment//8 对齐参数
enum Password {
case none//1
case number(Int, Int, Int, Int)//32
case gesture(String)//16
case otherPassword//1
}
var pas = Password.none
MemoryLayout.stride(ofValue: pas)//40 系统分配的空间
MemoryLayout.size(ofValue: pas)//33 实际占用的空间
MemoryLayout.alignment(ofValue: pas)//8 对齐参数
MemoryLayout<Password>.stride//40 系统分配的空间
MemoryLayout<Password>.size//33 实际占用的空间
MemoryLayout<Password>.alignment//8 对齐参数
enum Password {
case none//1
// case number(Int, Int, Int, Int)//32
case gesture(String)//16
case otherPassword//1
}
var pas = Password.none
MemoryLayout.stride(ofValue: pas)//16 系统分配的空间
MemoryLayout.size(ofValue: pas)//16 实际占用的空间
MemoryLayout.alignment(ofValue: pas)//8 对齐参数
MemoryLayout<Password>.stride//16 系统分配的空间
MemoryLayout<Password>.size//16 实际占用的空间
MemoryLayout<Password>.alignment//8 对齐参数
enum Password {
case none//1
// case number(Int, Int, Int, Int)//32
case gesture(String)//16
case otherPassword//1
}
var pas = Password.gesture("2222")
MemoryLayout.stride(ofValue: pas)//16 系统分配的空间
MemoryLayout.size(ofValue: pas)//16 实际占用的空间
MemoryLayout.alignment(ofValue: pas)//8 对齐参数
MemoryLayout<Password>.stride//16 系统分配的空间
MemoryLayout<Password>.size//16 实际占用的空间
MemoryLayout<Password>.alignment//8 对齐参数
网友评论