美文网首页
Swift5.2-枚举

Swift5.2-枚举

作者: Gomu_iOS | 来源:发表于2020-09-04 12:42 被阅读0次

    一、声明

    • 内容仅作为博主个人学习的一个总结输出,仅供参考,若对你产生了一丝帮助,荣幸之至。

    二、定义

    • 枚举类型是为一组相关联的值定义的一个公共类型,使得这些关联值能够在代码中以类型安全的方式进行处理。

    三、作用

    • 能够提供计算属性,用于支持枚举当前值之外的额外的信息
    • 能够提供实例方法,用于支持与枚举所代表的值相关的功能
    • 能够定义初始化方法,提供初始枚举项的值
    • 能够支持扩展, 可以在原始实现的基础上扩展其功能
    • 能够遵守协议,用于提供一切标准的功能

    四、语法

    • 使用enum关键字引入枚举,并将其整个定义放在{}中
    enum <#name#> {
        case <#case#>
    }
    
    • 枚举的定义与使用
    enum CompassPoint {
        case north
        case west
        case east
        case south
    }
    //: 多个枚举写在一行中。
    enum CompassPoint {
        case north,west,east,south
    }
    
    //: 每个枚举定义都定义了一个新类型
    var direction : CompassPoint = .north
    var direction = CompassPoint.north
    
    • Switch语句匹配枚举值
    let direction : CompassPoint = .north
    switch direction {
    case .east:
        print("ease")
    case .north:
        print("north")
    case .west:
        print("west")
    case .south:
        print("south")
    }
    //: 如果运行的时候,在switch direction { 这行报警告Switch condition evaluates to a constant的话,可以把要声明的变量放到函数外
    
    • 迭代枚举项

    通过在枚举名称后使用: CaseIterable,可以使枚举,拥有一个关于所有枚举项的集合。调用枚举类型的allCases属性,可以获取这个集合。

    enum CompassPoint : CaseIterable{
        case north,west,east,south
    }
    print(CompassPoint.allCases) //: log:[GCD闭包浅尝.CompassPoint1.north, GCD闭包浅尝.CompassPoint1.west, GCD闭包浅尝.CompassPoint1.east, GCD闭包浅尝.CompassPoint1.south]
    switch CompassPoint.allCases.first! {
    case .north:
        print("输出正确")
    default:
        print("输出失败")
    }
    //: eachCase每一项都是枚举类型的示例
    for eachCase in CompassPoint.allCases {
        /*north
         west
         east
         south*/
        print(eachCase) 
    }
    
    • 枚举关联值
    1. 枚举类型中在枚举项的旁边存贮额外的其他类型的值,这些值被称为关联值。并且每次在代码中使用有关联值的枚举项时,该关联值都会有所不同。
    2. Swift中可以定义枚举以存储任何给定类型的关联值,并且每个枚举项的值类型也可以不同。
    enum ProductCode {
        case upc(Int,Int,Int,Int) //: 通用商品条码
        case qrCode(String) //: 二维码
    }
    
    //: 使用
    var productCode = ProductCode.upc(1, 22, 333, 4444)
    //: let 放()里面
    switch productCode {
    case .upc(let x, let y, let z, let zz):
        print("从switch语句中提取的相匹配的枚举项的关联值为x:\(x) y:\(y) z:\(z) zz:\(zz)")
    case ProductCode.qrCode(let str):
        print("从switch语句中提取的相匹配的枚举项的关联值为:\(str)")
    }
    //: log: 从switch语句中提取的相匹配的枚举项的关联值为x:1 y:22 z:333 zz:4444
    
    productCode = ProductCode.qrCode("二维码哈")
    //: let 放前面
    switch productCode {
    case let .upc(x, y, z, zz):
        print("从switch语句中提取的相匹配的枚举项的关联值为x:\(x) y:\(y) z:\(z) zz:\(zz)")
    case let .qrCode(str):
        print("从switch语句中提取的相匹配的枚举项的关联值为:\(str)")
    }
    //: log: 从switch语句中提取的相匹配的枚举项的关联值为:二维码哈
    
    • 枚举原始值

    联值的示例中展示了枚举如何声明它们存储不同类型的关联值。作为关联值的替代,枚举也可以预先填充默认值(称为原始值),它们都是相同的类型。

    enum NameType : String{
        case Gomu = "gomu"
        case Anna = "anna"
        case Bob = "bob"
    }
    let name = NameType.Gomu
    print(name.rawValue)//: log: gomu
    //: 枚举NameType的原始值被定义为String类型,并被设置原始值。
    //: 原始值可以是字符串,字符或任何整数或浮点数类型。
    //: 每个原始值在其枚举声明中必须是唯一的。
    
    • 隐式分配原始值

    使用原始值为整数或字符串类型的枚举时,可以不用为每个case显式分配原始值。因为Swift会自动为我们分配值。

    enum Planet: Int,CaseIterable {
        case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
    }
    var planetOutStr = "枚举类型Planet各项的原始值"
    for item in Planet.allCases {
        planetOutStr += "\(item) : \(item.rawValue):"
    }
    print(planetOutStr)//: 枚举类型Planet各项的原始值:mercury : 1 venus : 2 earth : 3 mars : 4 jupiter : 5 saturn : 6 uranus : 7 neptune : 8
    //: 后面的值会自动填充rawValue
    
    //: 原始值为字符串类型的枚举,每个枚举项隐式分配的原始值是该枚举项的名称。
    //: 把上面 Planet后面的 Int 改成 String 后
    //: log: 枚举类型Planet各项的原始值:mercury : 1 venus : venus earth : earth mars : mars jupiter : jupiter saturn : saturn uranus : uranus neptune : neptune 
    
    • 从原始值初始化

    如果使用原始值类型定义枚举,则枚举会自动接收一个参数名:rawValue参数类型:原始值类型的初始话方法,并返回枚举项或nil。我们可以使用此初始化方法尝试创建该枚举类型的新实例。

    let possiblePalnet = Planet.init(rawValue: 7)
    //: Planet类型的可选项。
    //: log: Optional(GCD闭包浅尝.ViewController.(unknown context at $10096b13c).(unknown context at $10096b218).Planet.uranus)
    //无法根据原始值匹配到枚举项的情况
    let possiblePalnet = Planet.init(rawValue: 9)//!< Planet类型的可选项。9已经超出了枚举的所有项的范围。log:nil
    //: 需要解包,可选绑定
    if let possiblePlanet = possiblePalnet {
        print(possiblePlanet)
        switch possiblePlanet {
        case .earth:
            print("地球")
        default:
            print("其他行星")
        }
    } else {
        print("没有找到合适的枚举项")
    }
    
    • 枚举的递归

    定义一个枚举时,若该枚举类型的某个case关联了一个或多个该枚举类型的值时,系统会自动提示,需要添加indirect关键字,因为此时的枚举类型已经被定义为了拥有递归结构的递归枚举

    //: 方式一
    //: 递归枚举,存储了三个数学表达式 使用`indirect`来表示枚举项时可递归调用的。
    enum ArithmeticExpression {
        case number(Int)
        indirect case addition(ArithmeticExpression, ArithmeticExpression)
        indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
    }
    
    //: 方式二
    //: 在枚举开始之前使用indirect关键字,为具有关联值的所有枚举项启用递归:
    indirect enum ArithmeticExpression {
        case number(Int)
        case addition(ArithmeticExpression, ArithmeticExpression)
        case multiplication(ArithmeticExpression, ArithmeticExpression)
    }
    
    //: 存储了一个为5的关联值
    let five = ArithmeticExpression.number(5)
    //: 存储了一个为6的关联值
    let six = ArithmeticExpression.number(6)
    //: 存储了一个为3的关联值
    let three = ArithmeticExpression.number(3)
    //: addition枚举项,关联了两个当前枚举类型的值。
    let sum = ArithmeticExpression.addition(five, six)
    //: multiplication枚举项,关联了两个当前枚举类型的值。
    let multiplication = ArithmeticExpression.multiplication(sum, three)//: 数学表达式的呈现形式。
    
    //:创建一个递归函数验证可递归性
    func arithmeticOperation(_ expression : ArithmeticExpression) -> Int {
        switch expression {
        case let .number(x):
            return x
        case let .addition(x, y):
            //: 此处x和y仍旧是表达式,所以需要先进行递归运算得出`Int`类型的关联值
            return arithmeticOperation(x) + arithmeticOperation(y)
        case .multiplication(let x, let y):
            //: 此处x和y仍旧是`ArithmeticExpression`,所以需要先进行递归运算得出`Int`类型的关联值
            return arithmeticOperation(x) * arithmeticOperation(y)
        }
    }
    print("嵌套的数学表达式进行递归调用后的结果是:\(arithmeticOperation(multiplication))")
    //: log:嵌套的数学表达式进行递归调用后的结果是:33
    

    相关文章

      网友评论

          本文标题:Swift5.2-枚举

          本文链接:https://www.haomeiwen.com/subject/ipcosktx.html