Swift 中枚举的基本用法

Swift 中枚举的基本用法,第1张

一、枚举语法
//枚举的语法:名称需要首字母大写
enum Direction {
    case north
    case south
    case west
    case east
}
//多个成员值可以出现在同一行中,要用逗号隔开
enum Direction2 {
    case north, south, west, east
}

注意:与 OC 不同的是,Swift 中的枚举在创建时不分配默认整数值。也就是说 north、south、west、east 不等于隐式的 0、1、2 和 3

二、使用 Switch 语句来匹配枚举值
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

注意: OC的枚举值只支持Int一种类型,Swift的枚举值支持四种类型: 整型(NSInteger)、浮点型(Double、Flaot)、字符串(String)、布尔类型(Bool)

十、总结 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关键字

可以参考文章 https://www.jianshu.com/p/d25860cf8757

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/993395.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存