天天看點

Swift實用小冊21: Generics泛型的使用

在本章中,你将學會​

​Generics​

​泛型的使用方法。

前言

和​

​Apple​

​​官網或者網上分享的教程類文章不同,我将以實際開發角度講述​

​Swift​

​​語言的一些概念和用法,友善大家更好地學習和掌握​

​Swift​

​語言。

這同時也是對自己學習​

​Swift​

​語言過程的知識整理。

如有錯誤,以你為準。

項目建立

我們建立一個​

​PlayGround​

​​項目,命名為​

​SwiftGenerics​

​。

Swift實用小冊21: Generics泛型的使用

泛型定義

泛型,是一種不确定的資料類型。

泛型允許我們在編寫代碼時使用一些以後才指定的類型,并能在執行個體化時作為參數指明這些類型。

簡單來說,泛型就是一個“​

​占位符​

​”,用來代替目前不确定的類型。

泛型函數

泛型函數使用到了一個“​

​_​

​”占位類型來代替參數值,進而提高代碼複用率,減少代碼量。示例:

func  gotoAppStore(appId: String) {
    let urlPrex = "itms-apps"
    let appUrl = urlPrex + "://itunes.apple.com/app/id" + appId
    let appNsUrl = NSURL(string: appUrl)
    UIApplication.shared.open(appNsUrl! as URL, options: [:], completionHandler: nil)
}

gotoAppStore(appId: "App的ID")      

上述代碼是我們學習過的通過傳入一個​

​String​

​​類型的​

​appId​

​​參數,然後跳轉到​

​AppStore​

​的方法。

調用的時候,我們會指定傳入的參數,這裡使用的參數是​

​appId​

​。

但如果我們使用泛型函數,就可以不指定參數,泛型可以将類型參數化。示例:

func  gotoAppStore(_ appId: String) {
    let urlPrex = "itms-apps"
    let appUrl = urlPrex + "://itunes.apple.com/app/id" + appId
    let appNsUrl = NSURL(string: appUrl)
    UIApplication.shared.open(appNsUrl! as URL, options: [:], completionHandler: nil)
}

gotoAppStore("App的ID")      

使用泛型函數,我們就不需要指定參數,直接調用方法,達到減少代碼量的效果,這也算是​

​Apple​

​官方極度追求代碼優雅的結果。

​Swift​

​标準庫是通過泛型代碼建構出來的,像我們之前學習過的數組、字典其實也都是泛型集合。

Swift實用小冊21: Generics泛型的使用

泛型類型

除了可以使用泛型函數減少代碼量外,我們還可以自定義泛型類型,如果我們提前不知道需要接受到的資料類型,我們就可以先定義好一個泛型類型,然後确定類型後直接調用方法。示例:

struct Example<ArrayElement> {
    var items = [ArrayElement]()

    mutating func push(_ item: ArrayElement) {
        items.append(item)
    }
}      

上述代碼中,我們定義了一個自定義類型的結構體​

​Example​

​​,在​

​Example​

​​結構體中,我們聲明了一個​

​items​

​數組,它也是自定義類型的。

然後寫了一個方法,通過泛型函數的方法傳入參數,将傳入的參數添加到自定義類型的​

​items​

​數組中。

我們可以發現,我們在聲明數組時是沒有指定這個數組是什麼類型的,​

​Example​

​結構體傳入也是,它就是泛型類型。

這樣在我們在後面确定好傳入的參數類型後,我們就不需要重新修改數組的類型。示例:

var exampleStrings = Example<String>()
exampleStrings.push("文如秋雨")      

上述代碼中,我們聲明了一個​

​exampleStrings​

​​變量,它給​

​Example​

​​結構體定義了​

​String​

​​類型,後面我們就可以直接調用​

​push​

​傳入相應類型的參數即可。

關聯類型

在我們定義協定時,我們對于協定中的屬性也可以使用到泛型的方法,這裡提及一個關聯屬性的概念,也就是我們在協定中可以先不定義屬性的類型,而在使用的時候再确定屬性的類型。示例:

protocol Person {
    associatedtype FullName
    mutating func push(_ item: FullName)
}      

上述代碼中,我們定義了一個​

​Person​

​​協定,然後使用​

​associatedtype​

​關鍵字聲明了一個還不确定類型的參數​

​FullName​

​。

然後依舊寫了一個接收泛型函數的方法​

​push​

​​,我們再定義一個​

​class​

​來遵循這個協定。示例:

class People: Person {

    typealias FullName = String

    func push(_ item: String) {
        print("輸入的FullName是String")
    }
}

var exampleStrings2 = People()
exampleStrings2.push("文如秋雨")      

上述代碼中,我們定義了一個類​

​People​

​​,遵循​

​Person​

​​協定,然後調用​

​typealias​

​​關鍵字,給​

​FullName​

​​參數設定了一個關聯類型​

​String​

​。

然後在方法中傳入參數,列印輸出文字。

我們可以通過上面的方法知道,使用關聯類型時,我們就不需要在提前設定參數的類型,在我們實際業務中使用到了我們再定義,也就不用老是修改代碼,進而提高代碼複用率,減少代碼量。

Swift實用小冊21: Generics泛型的使用