1. 程式人生 > >Swift-列舉的基本學習和高階使用

Swift-列舉的基本學習和高階使用

  • 在 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 資料
            }
        }