最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Swift?enum枚舉類型使用詳解

 更新時(shí)間:2022年11月22日 16:09:41   作者:season_zhu  
這篇文章主要為大家介紹了Swift?enum枚舉類型的使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

我一直在思考如何去講解Swift中的枚舉類型,它是如此讓人熟悉,不免就讓你跟著編程經(jīng)驗(yàn)走,列舉幾個(gè)狀態(tài)就感覺(jué)萬(wàn)事大吉了。它是如此讓人陌生,當(dāng)你深刻的理解其廣泛的用途后,你不得不嘆服蘋果在設(shè)計(jì)enum是多么讓人眼前一亮。

我思來(lái)想去,還是從Swift中最有特點(diǎn)的兩個(gè)系統(tǒng)枚舉入手:Optional和Result,而著名的第三庫(kù)中選擇的話,Alamofire中細(xì)化的AFError也是全面理解Swift中enum的很好的范例。

AFError

由于Alamofire中AFError這個(gè)文件中注釋加上代碼已經(jīng)接近900行了,所以我在舉例說(shuō)明中會(huì)精簡(jiǎn)很大一部分,通過(guò)拋磚引玉的方式讓大家了解Swift中的enum的特點(diǎn)特色。

import Foundation
public enum AFError: Error {
    /// The underlying reason the `.urlRequestValidationFailed`
    public enum URLRequestValidationFailureReason {
        /// URLRequest with GET method had body data.
        case bodyDataInGETRequest(Data)
    }
    /// `URLRequest` failed validation.
    case urlRequestValidationFailed(reason: URLRequestValidationFailureReason)
}
// MARK: - Error Descriptions
extension AFError: LocalizedError {
    public var errorDescription: String? {
        switch self {
        case .explicitlyCancelled:
            return "Request explicitly cancelled."
        case let .invalidURL(url):
            return "URL is not valid: \(url)"
        case let .parameterEncodingFailed(reason):
            return reason.localizedDescription
        case let .parameterEncoderFailed(reason):
            return reason.localizedDescription
        case let .multipartEncodingFailed(reason):
            return reason.localizedDescription
        case let .requestAdaptationFailed(error):
            return "Request adaption failed with error: \(error.localizedDescription)"
        case let .responseValidationFailed(reason):
            return reason.localizedDescription
        case let .responseSerializationFailed(reason):
            return reason.localizedDescription
        case let .requestRetryFailed(retryError, originalError):
            return """
            Request retry failed with retry error: \(retryError.localizedDescription), \
            original error: \(originalError.localizedDescription)
            """
        case .sessionDeinitialized:
            return """
            Session was invalidated without error, so it was likely deinitialized unexpectedly. \
            Be sure to retain a reference to your Session for the duration of your requests.
            """
        case let .sessionInvalidated(error):
            return "Session was invalidated with error: \(error?.localizedDescription ?? "No description.")"
        #if !(os(Linux) || os(Windows))
        case let .serverTrustEvaluationFailed(reason):
            return "Server trust evaluation failed due to reason: \(reason.localizedDescription)"
        #endif
        case let .urlRequestValidationFailed(reason):
            return "URLRequest validation failed due to reason: \(reason.localizedDescription)"
        case let .createUploadableFailed(error):
            return "Uploadable creation failed with error: \(error.localizedDescription)"
        case let .createURLRequestFailed(error):
            return "URLRequest creation failed with error: \(error.localizedDescription)"
        case let .downloadedFileMoveFailed(error, source, destination):
            return "Moving downloaded file from: \(source) to: \(destination) failed with error: \(error.localizedDescription)"
        case let .sessionTaskFailed(error):
            return "URLSessionTask failed with error: \(error.localizedDescription)"
        }
    }
}
extension AFError.URLRequestValidationFailureReason {
    var localizedDescription: String {
        switch self {
        case let .bodyDataInGETRequest(data):
            return """
            Invalid URLRequest: Requests with GET method cannot have body data:
            \(String(decoding: data, as: UTF8.self))
            """
        }
    }
}

我們先一點(diǎn)點(diǎn)的分析吧:

  • enum是一種特殊的struct!
  • enum可以遵守協(xié)議,你看開(kāi)頭一上來(lái)就是public enum AFError: Error,表示就是這個(gè)AFError遵守Error協(xié)議,感興趣的可以看看Error到底是什么喔。
  • enum是可以帶參數(shù)的,我們看這個(gè)例子case urlRequestValidationFailed(reason: URLRequestValidationFailureReason)。

這個(gè)urlRequestValidationFailed帶了一個(gè)reason參數(shù),這個(gè)參數(shù)的類型是URLRequestValidationFailureReason,仔細(xì)看URLRequestValidationFailureReason,它其實(shí)也是個(gè)枚舉,并且?guī)?shù):

public enum URLRequestValidationFailureReason {
    /// URLRequest with GET method had body data.
    case bodyDataInGETRequest(Data)
}

怎么樣,有點(diǎn)暈了沒(méi)?夠酸爽了吧?這還不夠呢,我們接著看:

enum不僅能帶參數(shù)、遵守協(xié)議,還能寫分類,并擴(kuò)展只讀計(jì)算屬性與函數(shù),extension AFError: LocalizedError中就是遵守LocalizedError協(xié)議,并實(shí)現(xiàn)LocalizedError協(xié)議中的屬性var errorDescription: String?。

我們看看這個(gè)只讀計(jì)算屬性的里面其中的一個(gè)實(shí)現(xiàn):

case let .urlRequestValidationFailed(reason):
    return "URLRequest validation failed due to reason: \(reason.localizedDescription)"

這個(gè)case let的意思是:如果是urlRequestValidationFailed這種情況,獲取這個(gè)枚舉中的reason參數(shù),并且進(jìn)行字符串表達(dá),除了上面這種表達(dá),經(jīng)常的書寫方式還有下面幾種:

/// 將let放在取枚舉值的地方,我個(gè)人比較喜歡這種寫法
case .urlRequestValidationFailed(let reason):
/// 不關(guān)心枚舉帶參,用_代替
case .urlRequestValidationFailed(_):
/// 直接只顯示枚舉的狀態(tài),省略參數(shù)顯示
case .urlRequestValidationFailed:

最后一個(gè)extension AFError.URLRequestValidationFailureReason展示了在內(nèi)嵌的在AFError中的URLRequestValidationFailureReason類型應(yīng)該如何編寫分類。

怎么樣?單單看一個(gè)Alamofire的AFError就有不少的收獲吧?

Swift中的enum,是我目前學(xué)習(xí)過(guò)的編程語(yǔ)言中功能最強(qiáng)大的enum了。

Result

下面的是官方的Result的源碼,我只寫出了主干功能,大家看了,想想enum又支持什么功能呢?

@frozen public enum Result<Success, Failure> where Failure : Error {
    /// A success, storing a `Success` value.
    case success(Success)
    /// A failure, storing a `Failure` value.
    case failure(Failure)
    /// 其他的內(nèi)容我省略了
}

官方提供的Result枚舉在Swift5之后才正式上線,而Github開(kāi)源的,我們可以看這個(gè)庫(kù)Result,它的.gitignore創(chuàng)建于6年前,可以看到Result類型的出現(xiàn)并不是偶然,它的出現(xiàn)更多是因?yàn)楣δ苌系脑V求。

當(dāng)前的異步回調(diào)中,最常見(jiàn)的情況有兩種:回調(diào)成功抑或回調(diào)失敗,在早期的Swift回調(diào)中,我們經(jīng)常看見(jiàn)這樣寫:

typealias Callback<Success, SomeError: Error> = (Success?, SomeError?) -> Void

因?yàn)槲抑阑卣{(diào)到底是否成功,所以Success與SomeError都是可選類型,使用Result類型后,我們就可以這么寫了:

typealias ResultCallback<Success, SomeError: Error> = (Result<Success, SomeError>) -> Void

回調(diào)的結(jié)果,有兩種情況,真實(shí)可靠——case success和case failure,直接減少了可選類型的使用,也就精簡(jiǎn)了判空的邏輯。

通過(guò)Result這個(gè)枚舉,我們可以看出Swift中的enum是支持泛型的?。。?/p>

如果你一直使用過(guò)Alamofire和Kingfisher,你會(huì)發(fā)現(xiàn)它們里面的回調(diào)變遷也是圍繞這個(gè)上面兩個(gè)閉包的例子進(jìn)行演化的。

最后來(lái)介紹一下Swift中的可選類型。

Optional

下面的是官方的Optional的源碼,我只寫出了主干功能,是不是和Result非常相似呢?

@frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral {
    /// The absence of a value.
    ///
    /// In code, the absence of a value is typically written using the `nil`
    /// literal rather than the explicit `.none` enumeration case.
    case none
    /// The presence of a value, stored as `Wrapped`.
    case some(Wrapped)
}

而我經(jīng)??匆?jiàn)的String?這個(gè)寫法,不過(guò)是Optional<String>的糖語(yǔ)法罷了。

最后舉一個(gè)enum的典型例子

enum NumberType: String {
    case one, two, three, four, five
}
let s: NumberType = .one
print(s.rawValue)

s.rawValue的類型是String,而打印出來(lái)的就是字符串"one"。

這種enum NumberType: String寫法,本質(zhì)上告訴編譯器枚舉中的rawValue值是String類型,怎么樣,有木有有點(diǎn)暈?zāi)兀?/p>

大家思考一下下面這種情況:

enum NumberValue: Int {
    case one = 3, two, three, four, five
}

NumberValue.two.rawValue是什么呢?

總結(jié)

Swift中的enum,不僅是過(guò)去認(rèn)知中僅僅表示狀態(tài)的簡(jiǎn)單類型,它有以下這些特性:

  • 支持遵守協(xié)議
  • 支持泛型使用
  • 支持編寫擴(kuò)展
  • 支持帶參數(shù)
  • 支持繼承基礎(chǔ)數(shù)據(jù)類型,表示枚舉的rawValue的類型

還有其他有點(diǎn)意思的特性可能目前還沒(méi)有概括全面,我想表達(dá)的是,enum的設(shè)計(jì)是顛覆性,而靈活運(yùn)用這些enum特性,才是最難的。

之所以會(huì)先講解enum是因?yàn)樗臀覀冃枰v解的網(wǎng)絡(luò)請(qǐng)求封裝庫(kù)Moya非常密切。

以上就是Swift enum枚舉類型使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Swift enum枚舉類型的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 10個(gè)驚艷的Swift單行代碼

    10個(gè)驚艷的Swift單行代碼

    這篇文章主要為大家分享了10個(gè)驚艷的Swift單行代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Swift編程中實(shí)現(xiàn)希爾排序算法的代碼實(shí)例

    Swift編程中實(shí)現(xiàn)希爾排序算法的代碼實(shí)例

    希爾排序是對(duì)插入排序的一種改進(jìn)版本,算法本身并不穩(wěn)定,存在優(yōu)化空間,這里我們來(lái)講一下希爾排序的大體思路及Swift編程中實(shí)現(xiàn)希爾排序算法的代碼實(shí)例
    2016-07-07
  • 關(guān)于swift的個(gè)人小結(jié)

    關(guān)于swift的個(gè)人小結(jié)

    本文是個(gè)人對(duì)于目前學(xué)習(xí)swift的一些心得的匯總,這里分享給大家,希望大家能夠喜歡
    2016-12-12
  • Swift編程中的一些類型轉(zhuǎn)換方法詳解

    Swift編程中的一些類型轉(zhuǎn)換方法詳解

    這篇文章主要介紹了Swift編程中的一些類型轉(zhuǎn)換方法詳解,是Swift入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-11-11
  • Swift開(kāi)發(fā)之UITableView狀態(tài)切換效果

    Swift開(kāi)發(fā)之UITableView狀態(tài)切換效果

    這篇文章主要介紹了Swift開(kāi)發(fā)之UITableView狀態(tài)切換效果的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-08-08
  • Swift算法實(shí)現(xiàn)逐字翻轉(zhuǎn)字符串的方法示例

    Swift算法實(shí)現(xiàn)逐字翻轉(zhuǎn)字符串的方法示例

    大家都知道翻轉(zhuǎn)字符串在字符串算法中算是比較常見(jiàn)的,下面這篇文章主要介紹了Swift算法實(shí)現(xiàn)逐字翻轉(zhuǎn)字符串的方法,文中給出了詳細(xì)的示例代碼,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-03-03
  • 窺探Swift編程中的錯(cuò)誤處理與異常拋出

    窺探Swift編程中的錯(cuò)誤處理與異常拋出

    本文給大家整理些關(guān)于Swift編程中的錯(cuò)誤處理與異常拋出,本文介紹的非常詳細(xì),基于參考價(jià)值,特此分享腳本之家平臺(tái)供大家學(xué)習(xí)
    2016-02-02
  • Swift 3.0基礎(chǔ)學(xué)習(xí)之?dāng)U展

    Swift 3.0基礎(chǔ)學(xué)習(xí)之?dāng)U展

    擴(kuò)展是向一個(gè)已有的類、結(jié)構(gòu)體或枚舉類型添加新的功能(在swift中擴(kuò)展沒(méi)有名字)。相當(dāng)于Objective-C中Category(OC中可以有名字的,而且只能擴(kuò)展類)。這篇文章主要介紹了Swift 3.0基礎(chǔ)學(xué)習(xí)之?dāng)U展的相關(guān)資料,需要的朋友可以參考下。
    2017-03-03
  • 利用swift實(shí)現(xiàn)卡片橫向滑動(dòng)動(dòng)畫效果的方法示例

    利用swift實(shí)現(xiàn)卡片橫向滑動(dòng)動(dòng)畫效果的方法示例

    卡片橫向滑動(dòng)動(dòng)畫效果相信對(duì)大家來(lái)說(shuō)都不陌生,下面這篇文章主要給大家介紹了關(guān)于利用swift實(shí)現(xiàn)卡片橫向滑動(dòng)動(dòng)畫效果的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-07-07
  • Swift中初始化init的方法小結(jié)

    Swift中初始化init的方法小結(jié)

    Swift有著超級(jí)嚴(yán)格的初始化方法,不僅強(qiáng)化了designated初始化方法的地位,所有不加修飾的init方法都需要在方法中確保非Optional的實(shí)例變量被賦值初始化,下面這篇文章主要給大家介紹了關(guān)于Swift中初始化init的相關(guān)資料,需要的朋友可以參考下。
    2018-04-04

最新評(píng)論

察雅县| 永登县| 子长县| 朝阳县| 镇江市| 新泰市| 海晏县| 五常市| 沧州市| 淮阳县| 清水河县| 潍坊市| 平陆县| 高邮市| 乐都县| 清镇市| 上饶县| 芮城县| 喜德县| 沂南县| 山东| 自贡市| 普陀区| 西城区| 烟台市| 黔南| 绥江县| 长乐市| 永平县| 开原市| 英山县| 漳州市| 曲水县| 长治县| 沐川县| 元朗区| 冕宁县| 周至县| 长海县| 平武县| 库车县|