枚举为一组相关的值定义了一个共同的类型,使你可以在你的代码中以类型安全的方式来使用这些值
枚举类型是一等(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())
网友评论