Swift中的枚举比OC中的枚举强大很多。
1、简单使用
// 使用enum关键字 定义枚举
enum HFMethod {
case Add
case Sub
case Mul
case Div
}
// 可以连在一起写,成员之间用,隔开
enum HFDirection {
case North, Sourth, East, West
}
// 初始化方法
var method: HFMethod = .Sub
var direction = HFDirection.Sourth
2、枚举和swift语句使用
var method: HFMethod = .Sub
// 如果case中没有包含所有值,需要填写default,
// 如果包含了所有值 可以不写
switch(method) {
case .Sub:
print("sub")
case .Mul:
print("mul")
default:
print("default")
}
3、枚举的原始值
oc中枚举的本质就是整数,所以oc中枚举的原始值默认是从0开始的,如果手动设置个某个整数,之后的不设置的情况下自动+1。
swift中的枚举默认是没有原始值的
如果定义的枚举类型是int,默认从0开始,
如果定义的枚举是string类型,默认是枚举成员名字
enum HFDirection {
case North, Sourth, East, West
}
HFDirection 默认是没有枚举值的
若修改为:
// 设定为Int类型枚举,原始值默认从0开始,依此+1
enum HFMethod: Int {
case Add
case Sub
case Mul
case Div
}
// 设定为String类型枚举,原始值默认为成员名
enum HFDirection: String {
case North, Sourth, East, West
}
// 设定Double类型枚举,原始值默认是1.0,依此+1
// 设置有效的原始值数据更有价值
enum Constants: Double {
case π = 3.14159
case e = 2.71828
case φ = 1.61803398874
case λ = 1.30357
}
let direction = HFDirection.Sourth
print("direction.rawValue = \(direction.rawValue), direction = \(direction)")
let method: HFMethod = .Sub
print("method.rawValue = \(method.rawValue), method = \(method)")
let constant = HFMathConstants.e
print("constant.rawValue = \(constant.rawValue), contant = \(constant)")
打印输出:
direction.rawValue = Sourth, direction = Sourth
method.rawValue = 1, method = Sub
constant.rawValue = 2.71828, contant = e
枚举值和原始值之间的转化
// 可以使用原始值初始化一个枚举值,但是初始化返回的是可选类型
let newMethod = HFMethod(rawValue: 3)
if let m = newMethod {
print("m = \(m)")
} else {
print("创建失败")
}
打印输出:
m = Div
若
let newMethod = HFMethod(rawValue: 5)
打印输出:
创建失败
4、枚举的关联值
可以将额外的信息附加到枚举值中,使用关联值,每一个枚举值就可以是在某种模式下的一些特定值。
enum HFTBType {
case Buy(name: String, num: Int) //买什么 买了多少
case ReSale(name: String, num: Int) // 转卖什么 卖了多少
}
var tbBuy = HFTBType.Buy(name: "T恤", num: 3)
var tbResale = HFTBType.ReSale(name: "水杯", num: 2)
// 使用switch语句获取到关联值
switch tbBuy {
case .Buy(let name, let num):
print("- -第一种方法获取 buy \(name) nums = \(num)")
case let .ReSale(name, num):
print("- -第一种方法获取 resale \(name), nums = \(num)")
}
// 使用模式匹配获取到关联值
if case let HFTBType.ReSale(name, num) = tbResale {
print("- -第二种方法获取 - resale \(name), nums = \(num)")
}
输出:
- -第一种方法获取 buy T恤 nums = 3
- -第二种方法获取 - resale 水杯, nums = 2
5、递归枚举
关键字indirect,可以在整个enum前面 也可以需要递归的case 前面
indirect enum HFMathExpr {
case number(Int)
case sum(HFMathExpr,HFMathExpr)
case difference(HFMathExpr,HFMathExpr)
}
enum HFMathExpr {
case number(Int)
indirect case sum(HFMathExpr,HFMathExpr)
indirect case difference(HFMathExpr,HFMathExpr)
}
//定义枚举变量,可以直接通过number来定义,也可以通过sum/difference递归定义
let ten = HFMathExpr.number(10)
let five = HFMathExpr.number(5)
let sum = HFMathExpr.sum(ten, five)
let difference = HFMathExpr.difference(sum, five)
//取出枚举变量中的数据进行加减运算
//需要注意的是:如果传入sum/difference需要递归取出number值
func calculate(_ expr: HFMathExpr) -> Int {
switch expr {
case let .number(value):
return value
case let .sum(left, right):
return calculate(left) + calculate(right)
case let .difference(left, right):
return calculate(left) - calculate(right)
}
}
print("calculate(ten) = \(calculate(ten))")
print("calculate(five) = \(calculate(five))")
print("calculate(sum) = \(calculate(sum))")
print("calculate(difference) = \(calculate(difference))")
输出
calculate(ten) = 10
calculate(five) = 5
calculate(sum) = 15
calculate(difference) = 10
6、枚举中的属性
可以给枚举添加一个计算属性。
Swift中的属性分为存储属性和计算属性,
存储属性就是Objective-C中的数据成员,
计算属性不存储数据,但可以通过计算其他属性返回数据。
enum HFTBType {
case Buy(name: String, num: Int) //买什么 买了多少
case ReSale(name: String, num: Int) // 转卖什么 卖了多少
// 手续费
var fees: Int {
switch self {
case .Buy(_, let num):
return num*4
case let .ReSale(name, num):
return num*3
}
}
}
var tbBuy = HFTBType.Buy(name: "T恤", num: 3)
var tbResale = HFTBType.ReSale(name: "水杯", num: 2)
print("tbBuy.fees = \(tbBuy.fees), tbResale.fees = \(tbResale.fees)")
输出:
tbBuy.fees = 12, tbResale.fees = 6
7、枚举中的方法
实例方法
静态方法,可以通过一个非枚举类型创建一个枚举,或其他诉求
enum HFTBType {
case Buy(name: String, num: Int) //买什么 买了多少
case ReSale(name: String, num: Int) // 转卖什么 卖了多少
// 手续费
var fees: Int {
switch self {
case .Buy(_, let num):
return num*4
case let .ReSale(_, num):
return num*3
}
}
func description() -> String {
switch self {
case .Buy(let name, let num):
return "buy \(name) nums = \(num)"
case let .ReSale(name, num):
return "buy \(name) nums = \(num)"
}
}
//添加静态方法
static func fromSlang(type: String,name: String, num:Int) -> HFTBType? {
if type == "Buy" {
return HFTBType.Buy(name: name, num: num)
} else if type == "ReSale" {
return HFTBType.ReSale(name: name, num: num)
}
return nil
}
}
var tbBuy = HFTBType.Buy(name: "T恤", num: 3)
var tbResale = HFTBType.ReSale(name: "水杯", num: 2)
print("tbBuy.description = \(tbBuy.description()) \ntbResale.description = \(tbResale.description())")
var tbType = HFTBType.fromSlang(type: "Buy", name: "SKirt", num: 9)
if let type = tbType {
print("type.description = \(type.description())")
} else {
print("创建失败")
}
输出
tbBuy.description = buy T恤 nums = 3
tbResale.description = buy 水杯 nums = 2
type.description = buy SKirt nums = 9
若
var tbType = HFTBType.fromSlang(type: "Buy1", name: "SKirt", num: 9)
则会输出创建失败
8、枚举嵌套
enum HFTrafficLight {
case red
case yellow
case green
enum Signal {
case slow
case stop
case go
}
}
// 使用嵌套的枚举
let light = HFTrafficLight.green
switch light {
case .green:
print("green.")
case .red:
print("red.")
case .yellow:
print("yellow.")
}
let signal: HFTrafficLight.Signal = .go
switch signal {
case .slow:
print("Slow down.")
case .stop:
print("Stop.")
case .go:
print("Go.")
}
输出
green.
Go.
项目中:
服务器地址,环境变量 接口路径等使用嵌套枚举
9、遵循协议、添加扩展
枚举可以像结构体或类一样,遵循协议、添加扩展。
添加扩展最大的用途就是将枚举case 和 方法分离,可读性更强。
还可以在扩展中实现协议方法
enum HFTBType {
case Buy(name: String, num: Int) //买什么 买了多少
case ReSale(name: String, num: Int) // 转卖什么 卖了多少
// 手续费
var fees: Int {
switch self {
case .Buy(_, let num):
return num*4
case let .ReSale(_, num):
return num*3
}
}
}
extension HFTBType {
func description() -> String {
switch self {
case .Buy(let name, let num):
return "buy \(name) nums = \(num)"
case let .ReSale(name, num):
return "buy \(name) nums = \(num)"
}
}
//添加静态方法
static func fromSlang(type: String,name: String, num:Int) -> HFTBType? {
if type == "Buy" {
return HFTBType.Buy(name: name, num: num)
} else if type == "ReSale" {
return HFTBType.ReSale(name: name, num: num)
}
return nil
}
}