9.枚举

作者: LucXion | 来源:发表于2021-07-15 09:10 被阅读0次

    枚举为一组相关的值定义了一个共同的类型,使你可以在你的代码中以类型安全的方式来使用这些值

    枚举类型是一等(first-class)类型。它们采用了很多在传统上只被类(class)所支持的特性,例如 计算属性(computed properties),用于提供枚举值的附加信息,实例方法(instance methods),用于提供和枚举值相关联的功能。枚举也可以定义 构造函数(initializers)来提供一个初始值;可以在原始实现的基础上扩展它们的功能;还可以 遵循协议(protocols)来提供标准的功能。

    enum Point { // 枚举名称取单数名称
        case a,b,c // 枚举成员可以写在同一行用逗号隔开,a,b,c不会隐式的被设置成0,1,2,这些枚举成员本身就是完备的值,这些值的类型是已经明确定义好的 Point 类型。
    }
    
    let p:Point = .a //明确类型时,可以用更短的语法来给它设置枚举值
    

    CaseIterable 协议

    enum Point:CaseIterable {
        case a,b,c
    }
    print(Point.allCases.count) // CaseIterable 协议会新增一个 allCases数组
    for point in Point.allCases {
        print(point)
    }
    

    关联值

    enum Code {
    //    定义一个名为 Code 的枚举类型,它的一个成员值是具有 (Int,Int,Int,Int) 类型关联值的 upc,另一个成员值是具有 String 类型关联值的 qrCode
        case upc(Int,Int,Int,Int)
        case qrCode(String)
    }
    var codes:[Code] = [.upc(1, 1, 3, 4),.qrCode("abc")]
    let code = codes.first!
    switch code {
        case.upc(let one,let two,let three,let four) where two == 1:
        print(one,two,three,four)
        case.qrCode:
            print("qrCode = \(code)")
        default:
            print("default")
    }
    // fallthrough 会强行穿透到下一个支干,不做条件判断
    

    原始值

    原始值和关联值是不同的。原始值是在定义枚举时被预先填充的值。对于一个特定的枚举成员,它的原始值始终不变。关联值是创建一个基于枚举成员的常量或变量时才设置的值,枚举成员的关联值可以变化。

    enum Point :String{ // 必须明确枚举类型,才会有原始值
        case East,West // 默认字符串类型的枚举值,原始值等于本身的字符串,默认整数类型的枚举值,原始值由0开始,+1递增
        // 明确类型的枚举值不能设置关联值
    }
    let point = Point.init(rawValue: "East")// 有原始值的枚举值,会自动创建一个构造方法,可失败构造器
    // point为可选值
    if let p = point {
        print(p.rawValue)
    }else {
        print("fail")
    }
    

    递归枚举

    允许枚举成员以枚举实例作为关联值

    indirect enum ArithmeticExpression {// indirect关键字允许枚举成员以枚举实例作为关联值,
        case Num(Int)
        case ArithmeticAdd(ArithmeticExpression,ArithmeticExpression)// indirect,可以仅加在关联的成员case前
        case ArithmeticSub(ArithmeticExpression,ArithmeticExpression)
        case ArithmeticMul(ArithmeticExpression,ArithmeticExpression)
        case ArithmeticDiv(ArithmeticExpression,ArithmeticExpression)
        func excute() -> Int {
            let at = self
            switch at {
            case .Num(let num):
                return num
            case .ArithmeticAdd(let left,let right):
                return left.excute()+right.excute()
            case .ArithmeticSub(let left,let right):
                return left.excute()+right.excute()
            case .ArithmeticMul(let left,let right):
                return left.excute()*right.excute()
            case .ArithmeticDiv(let left,let right):
                return left.excute()/right.excute()
            }
        }
    }
    // (1+2)*10 / 5
    let num1 = ArithmeticExpression.Num(1)
    let num2 = ArithmeticExpression.Num(2)
    let num10 = ArithmeticExpression.Num(10)
    let num5 = ArithmeticExpression.Num(5)
    
    let add = ArithmeticExpression.ArithmeticAdd(num1, num2)
    let mul = ArithmeticExpression.ArithmeticMul(add, num10)
    let div = ArithmeticExpression.ArithmeticDiv(mul, num5)
    
    print(div.excute())
    

    相关文章

      网友评论

          本文标题:9.枚举

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