Swift-列舉的基本學習和高階使用
阿新 • • 發佈:2018-12-24
- 在 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 資料
}
}