Swift-枚举的基本学习和高级使用

时间:2023-01-24 09:18:29
  • 在 Swift 中,枚举类型是一等(first-class)类型
  • 枚举是一种数据类型, 为一组相关的值定义了一个共同的类型
  • Swift 中的 enum 与 Objective-C 的 enum 不同, Swift 的枚举成员在被创建时不会被赋予一个默认的整型值
  • Objective-C enum 的成员值只能为整型, 但 Swift 中的 enum 不仅可以是整型,还能是字符型或浮点型
  • Swift 中的 enum 除了成员值外,还有关联值(高级用法)

在学习 enum 的高级使用之前,首先需要了解 enum 的基本使用:

枚举的基本定义

enum Direction {
case north
case south
case east
case west
}

// 简写
enum Direction1 {
case north, south, east, west
}

// 用法:
// enum 常量
let direction = Direction.south
// enum 变量
var direction1 = Dreection.east
direction1 = .west

带有成员值的枚举

  • 原始值, 如果定义了一个原始值,且为 Int,默认递增
  • 如果在定义枚举类型的时候使用了原始值,那么将会自动获得一个初始化方法,这个方法接收一个叫做rawValue的参数,参数类型即为原始值类型,返回值则是枚举成员或nil
  • 关联值是创建一个基于枚举成员的常量或变量时才设置的值,枚举成员的关联值可以变化
// 定义了原始值(成员值)后,且为 Int,默认递增
enum Direction2: Int {
case north = 0
case south
case east
case west
}

// 定义原始值为字符串类型
enum Drection3: String {
case north = "NORTH"
case south = "SOUTH"
case east = "EAST"
case west = "WEST"
}

// 如果定义了原始值,可以通过 rowValue 获取存储的值
let direction2WestNumber = Direction2.west.rawValue // 2
let direction3EastString = Direction3.east.rawValue // "EAST"


使用 Switch 语句匹配枚举值

var direction = Direction.south
switch direction {
case .north:
print("N")
case .south:
print("S")
case .east:
print("E")
case .west:
print("W")
}

// 打印: "S"

注意:
当通过 switch 匹配枚举值时,如果每个属性都匹配到,不需要调用 default
当只匹配了部分属性时,必须要调用default

direction = .east
switch direction {
case .north:
print("N")
case .south:
print("S")
default:
print("other direction")
}
// 打印: "other direction"

枚举与关联值

  • Swift 的枚举中可以把其他类型的关联值和成员值一起存储起来使用
  • 如果需要的话,每个枚举成员的关联值类型可以各不相同

具体使用

enum ValueEnum {
case num(Int)
case score(Float)
case string(String)
case dict([String: AnyObject])
}

var value = ValueEnum.num(5)
switch value {
case .num(let n):
print("IntValue: \(n)")
case .score(let f):
print("FloatValue: \(f)")
case .string(let s):
print("StringValue: \(s)")
case .dict(let d):
print("DictValue: \(d)")
}

// 打印: IntValue: 5
// 当修改 枚举成员 value 的值后, switch 打印的结果:
value = ValueEnum.score(8.8)
// 打印: FloatValue: 8.8


value = ValueEnum.string("Hi Mazy")
// 打印: StringValue: Hi Mazy


value = ValueEnum.dict(["key":"value" as AnyObject])
// 打印: DictValue: ["key": value]

枚举关联值的实际使用示例

通过枚举返回网络请求的返回结果

1-定义枚举类型,关联请求结果,包含成功的 json 数据,以及失败错误信息 error 数据

enum ResponseResult {
case json([String: AnyObject])
case error(Error)
}

2-定义网络请求函数,通过闭包返回结果信息,结果信息类型为枚举

func getData(with url: String, completionHandler: @escaping (ResponseResult)->Void) {
Alamofire.request(url).responseJSON { (response) in
if let json = response.result.value as? [String: AnyObject] {
completionHandler(.json(json)) // 请求成功,关联 json 数据
} else {
if let error = response.error {
completionHandler(.error(error)) // 请求失败,关联 error 数据
}
}
}
}

3-调用网络请求方法,通过 switch 处理返回结果数据

getData(with: "https://httpbin.org/get") { (result) in
switch result {
case .json(let json): // 如果请求成功,获取枚举关联的 json 数据
print(json)
case .error(let error):
print(error) // 如果失败,获取枚举关联的 error 数据
}
}