//枚举的语法:名称需要首字母大写
enum Direction {
case north
case south
case west
case east
}
//多个成员值可以出现在同一行中,要用逗号隔开
enum Direction2 {
case north, south, west, east
}
二、使用 Switch 语句来匹配枚举值注意:与 OC 不同的是,Swift 中的枚举在创建时不分配默认整数值。也就是说 north、south、west、east 不等于隐式的 0、1、2 和 3
enum Direction {
case north, south, west, east
}
//使用 Switch 语句来匹配每一个单独的枚举值
let directionToHead = Direction.south
switch directionToHead {
case .north:
print("north")
case .south:
print("south")
case .west:
print("west")
case .east:
print("east")
}
三、遍历枚举的 case
可以通过在枚举名字 后面写 : CaseIterable 来允许枚举被遍历。Swift 会暴露一个包含对应枚举类型所有情况的集 合名为 allCases。
//在枚举名字: 后面写 CaseIterable,Swift 会暴露 allCase 集合
enum Direction: CaseIterable {
case north, south, west, east
}
//遍历枚举
for dir in Direction.allCases {
print(dir)
}
print(Direction.allCases.count) //获取枚举所有情况的个数
四、关联值
可以定义 Swift 枚举来存储任意给定类型的关联值,如果需要的话不同枚举成员关联值的类型 可以不同
//关联值
enum BarCode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarCode = BarCode.upc(1, 2, 3, 4)
print(productBarCode) //打印: upc(1, 2, 3, 4)
productBarCode = .qrCode("ABSDEFGHIJK")
print(productBarCode) //打印: qrCode("ABSDEFGHIJK")
//可以在 case 后面写 let 或者 在括号里面 写 let 定义相匹配的变量
switch productBarCode {
case .upc(let first, let second, let third, let fourth):
print("UPC: \(first), \(second), \(third), \(fourth)")
case let .qrCode(productCode):
print("QR code: \(productCode)")
}
五、原始值
枚举成员可以用相同类型的默认值预先填充(称为原始值)
注意:如果声明的时候不指定枚举类型就没有rawValue属性(包括关联值)
//枚举也可以有原始值
enum ControlCharacter: Character { //如果没有声明枚举的类型,是没有 rawValue 属性可以访问的
case tab = "\t"
case linefeed = "\n"
case carrigeReturn = "\r"
}
print(ControlCharacter.linefeed.rawValue) //输出结果是换行了
六、预设原始值
在 *** 作存储整数或字符串原始值枚举的时候,不必显式地给每一个成员都分配一个原始 值。当没有分配时,Swift 将会自动为你分配值
//预设原始值:预设west等于5,那么后面的值依次往后面加1
enum point: Int {
case west = 5
case north // 6
case east // 7
case south // 8
}
print(point.south.rawValue) //输出结果为:8
enum Point2: Int {
case west
case north
case east = 5
case south
}
//值得注意的是: 如果是给 east 赋值为 5, west 的值是从 0, north 的值是 1
print(Point2.south.rawValue) // 6
print(Point2.west.rawValue) // 0
print(Point2.north.rawValue) // 1
//预设原始值: 必须要定义枚举的类型
enum point: String {
case west
case north
case east
case south
}
print(point.south.rawValue) //输出结果为:south,此时可以不写 rawValue,它们输出的值是一样的
七、从原始值初始化
如果用原始值类型来定义一个枚举,那么枚举就会自动收到一个可以接受原始值类型的值初始化器(叫做 rawValue的形式参数)然后返回一个枚举成员或者 nil 。你可以使用这个初始 化器来尝试创建一个枚举的新实例
//预设原始值:预设west等于5,那么后面的值依次往后面加1
enum point: Int {
case west = 5
case north // 6
case east // 7
case south // 8
}
print(point.south.rawValue) //输出结果为:8
//也可以使用rawValue来创建或者初始化一个枚举值,最终可以获取枚举的具体值
let direction2 = point(rawValue: 9)
print(direction2 ?? 0) //如果direction2没有值的话,默认就是0
八、递归枚举
递归枚举是拥有另一个枚举作为枚举成员关联值的枚举。当编译器 *** 作递归枚举时必须插入间接寻址层。可以在声明枚举成员之前使用 indirect关键字来明确它是递归的
//如说表达式(5 + 4) * 2 在乘法右侧有一个数但有其他表达式在乘法的左侧
indirect enum Expression {
case number(Int)
case add(Expression, Expression)
case multiply(Expression, Expression)
}
let four = Expression.number(4)
let five = Expression.number(5)
let sum = Expression.add(four, five)
print(four)
print(sum)
let multiply = Expression.multiply(sum, Expression.number(2))
print(multiply)
//在函数中根据switch语句获取匹配的case条件
func eval(_ expression: Expression) -> Int {
//使用值绑定的方式
switch expression {
case .number(let value):
return value
case .add(let first, let second):
return eval(first) + eval(second)
case .multiply(let first, let second):
return eval(first) * eval(second)
}
}
print(eval(multiply)) // 18
十、总结 Swift中的枚举很强大enum中的 rawValue 是其中的计算属性如果声明的时候不指定枚举类型就没有rawValue属性(包括关联值)rawValue中的值存储在Mach-O中,不占用枚举的存储空间枚举值与rawValue不是同一个东西rawValue可以不写,如果是Int默认0,1,2…String等于枚举名称的字符串如果枚举中存在rawValue同时也会存在init(rawValue:)方法,用于通过rawValue值初始化枚举如果枚举遵守了CaseIterable协议,且不是关联值的枚举,我们可以通过enum.allCases获取到所有的枚举,然后通过for循环遍历我们可以使用switch对枚举进行模式匹配,如果只关系一个枚举还可以使用if case关联值枚举可以表示复杂的枚举结构关联值的枚举没有init方法,没有RawValue别名,没有rawValue计算属性enum可以嵌套enum,被嵌套的作用域只在嵌套内部结构体也可以嵌套enum,此时enum的作用域也只在结构体内enum中可以包含计算属性,类型属性但不能包含存储属性enum中可以定义实例方法和使用static修饰的方法,不能定义class修饰的方法如果想使用复杂结构的枚举,或者说是具有递归结构的枚举可以使用indirect关键字注意: OC的枚举值只支持Int一种类型,Swift的枚举值支持四种类型: 整型(NSInteger)、浮点型(Double、Flaot)、字符串(String)、布尔类型(Bool)
可以参考文章 https://www.jianshu.com/p/d25860cf8757
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)