iOS:Swift 枚举

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
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容