“东海帝王,奇迹的复活” — 《赛马娘第二季》
前言
枚举为一组相关值定义了一个通用类型,从而可以让你在代码中类型安全地操作这些值。
Swift中的枚举更加灵活,并且不需给枚举中的每一个成员都提供值。如果一个值(所谓“原始”值)要被提供给每一个枚举成员,那么这个值可以是字符串、字符、任意的整数值,或者是浮点类型。
而且,枚举成员可以指定任意类型的值来与不同的成员值关联储存,即枚举成员中的值可能是多种类型。枚举具有自己权限的一种类型,一句话:功能很强大,用法很nb。
枚举语法
/// 多行
enum RacingHorse {
case specialWeek
case silenceSuzuka
case goldShip
case mejiroMcQueen
}
/// 单行 用逗号隔开
enum RacingHorse {
case riceShower, grassWonder, biwaHayaHide
}
/// 使用
let firstHorse = RacingHorse.specialWeek
/// 类型推断
let secondHorse: RacingHorse = .riceShower
复制代码
关联值
这里就和我们平时使用的OC和C的枚举不一样了
/// 定义一个叫做 Barcode的枚举类型,它要么用 (Int, Int, Int, Int)类型的关联值获取 upc 值,要么用 String 类型的关联值获取一个 qrCode的值。
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
/// 关联了一个元组的Barcode.upc
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
/// 这时productBarcode的值会被Barcode.qrCode取代 这时的关联值为"ABCDEFGHIJKLMNOP"的字符串
复制代码
相关值可以作为常量或变量在switch的case中使用:
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
print("QR code: \(productCode).")
}
/// 如果都被提取成常量或者变量,可以提前标注
switch productBarcode {
case let .upc(numberSystem, manufacturer, product, check):
print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case var .qrCode(productCode):
print("QR code: \(productCode).")
}
复制代码
原始值
作为相关值的另一种选择,枚举成员可以用相同类型的默认值预先填充(称为原始值)。
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
复制代码
隐式指定的原始值
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
/// venus原始值为2 以此类推
enum racingHorse: String {
case specialWeek
case silenceSuzuka
case goldShip
case mejiroMcQueen
}
racingHorse.specialWeek的原始值为"specialWeek"
复制代码
可以通过rawValue属性来访问一个枚举成员的原始值
let earthsOrder = Planet.earth.rawValue /// earthsOrder is 3
let horseName = racingHorse.specialWeek.rawValue /// horseName is "specialWeek"
复制代码
从原始值初始化
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.Uranus
// 返回的是可选类型,原始值如果不存在将会是nil
复制代码
递归枚举
枚举在对序号考虑固定数量可能性的数据建模时表现良好,比如用来做简单整数运算的运算符。这些运算符允许你组合简单的整数数学运算表达式比如5到更复杂的比如5+4.
数学表达式的一大特征就是它们可以内嵌。比如说表达式(5 + 4) * 2 在乘法右手侧有一个数但其他表达式在乘法的左手侧。因为数据被内嵌了,用来储存数据的枚举同样需要支持内嵌——这意味着枚举需要被递归。
递归枚举是拥有另一个枚举作为枚举成员关联值的枚举。当编译器操作递归枚举时必须插入间接寻址层。你可以在声明枚举成员之前使用 indirect关键字来明确它是递归的。
自己写个例子,打游戏时有伤害计算什么的,要计算暴击,护甲什么的。例子烂,凑合看
indirect enum damage {
case number(Double)
case crit(damage, damage)
case reduce(damage, damage)
}
let attack = damage.number(100.0) /// 攻击力
let multipleCrit = damage.number(2.0) /// 暴击倍数
let multipleReduce = damage.number(0.8) /// 减伤
let attackOnce = damage.crit(attack, multipleCrit) /// 打出去伤害
let underAttack = damage.reduce(attackOnce, multipleReduce) /// 收到伤害
func evaluate(_ expression: damage) -> Double {
switch expression {
case let .number(attackValue):
return attackValue
case let .crit(attackValue, multiple):
return evaluate(attackValue) * evaluate(multiple)
case let .reduce(attackValue, multiple):
return evaluate(attackValue) * evaluate(multiple)
}
}
print(evaluate(underAttack))
/// print 160.0
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END