亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Swift3.0 泛型<T>

2019-11-14 10:12:05
字體:
來源:轉載
供稿:網友
泛型能夠讓開發者編寫自定義需求已經任意類型的靈活可用的的函數和類型。能夠讓我們避免重復的代碼。用一種清晰和抽象的方式來表達代碼的意圖。

1.泛型解決的問題

下面是一個非泛型的例子
func swapTwoIntValue(a: inout Int, b: inout Int){    let tempValue = a    a = b    b = tempValue}
這個函數用來交換兩個整形的數值
var a = 1var b = 2swapTwoIntValue(a: &a, b: &b)PRint(a, b)//2,1
對于這個例子,假如我們想交換兩個Double類型、或者是其他類型的值,就需要針對每個類型寫不同的方法,只是參數類型不同。為了解決這個問題,Swift提供了泛型,幫助我們來解決這個問題。
注意:Swift是安全的語言,不允許兩個不同類型互換值

2.泛型函數

下面是一個泛型的函數
func swapTwoValue<T>(a: inout T, b: inout T){    let tempValue = a    a = b    b = tempValue}
這個函數主體、功能跟上面的例子類似,用來交換兩個同樣類型的值,但是這個函數用 T 占位符來代替實際的類型。并沒有指定具體的類型,但是傳入的a ,b 必須是同一類型T。在調用這個函數的時候才能指定 T 是那種具體的類型。還有函數名后跟的那個 <T> 是函數定義的一個占位類型名,并不會查找T的具體類型
swapTwoValue(&oneInt, b: &twoInt)print("oneInt:/(oneInt),twoInt:/(twoInt)") // oneInt:3,twoInt:4var oneStr = "hello"var twoStr = "world"swapTwoValue(&oneStr, b: &twoStr)print("oneStr:/(oneStr),twoStr:/(twoStr)")// oneStr:world,twoStr:hellovar oneDouble = 10.01var twoDouble = 20.02swapTwoValue(&oneDouble, b: &twoDouble)print("oneDouble:/(oneDouble),twoDouble:/(twoDouble)")// oneDouble:20.02,twoDouble:10.01
這個例子用泛型完美的解決了上述的問題,只需要定義一個泛型函數,只要保證 傳入的兩個參數是同一個類型,就不用根據傳入參數的類型不同而寫不同的方法。

3.類型參數

在上面的泛型函數例子中,占位符T是類型參數的一個例子。類型參數指定并命名一個占位符類型,并用<>包裹,放在函數名后面。一旦一個參數類型確定,就可以指定參數類型,或者返回值的類型,還可以用作函數體的注釋類型。在調用的時候會被實際的類型替代,如傳遞的是Int,就替換為Int,如果傳入的是Double類型就替換為Double等等

4.命名類型參數

上面的泛型例子的 T,只是一個描述性的名字,通常用單一的字母來命名,例如:T、U、V等。T代表只是一個占位符,命名規則同駝峰命名法

5.泛型類型

除了定義泛型函數,還可以定義泛型類型。如Array,Dictionary的用法
下面展示一個非泛型版本棧
struct IntStack {    var items = [Int]()    mutating func push(item: Int) {        items.append(item)    }    mutating func pop(item: Int) -> Int {        return items.removeLast()    }}
這個是一個泛型版本的棧
struct Stack<T> {    var items = [T]()    mutating func push(item: T) {        items.append(item)    }    mutating func pop(item: T) -> T {        return items.removeLast()    }}
首先在函數名后面加<泛型類型名>,<>里面表明類型參數名。然后在函數主體里面完成跟非泛型棧類似的功能。這樣這個泛型結構體就不只能壓棧Int類型的值,還可以是其它類型
var stack = Stack<String>() //要在類型名后面加<類型名>stack.push("uno")stack.push("dos")stack.push("tres")stack.push("cuatro")print(stack.pop()) // cuatro

6.擴展一個泛型類型

可以擴展一個泛型類型,給這個泛型類型添加屬性、方法、下標等。
extension Stack{    //給泛型Stack擴展一個計算型屬性topItem,返回最上面的item    var topItem: T? {        return items.isEmpty ? nil : items[items.count-1]    }}

7.類型約束

在上面的SwapTwoVlues 和 Stack中,可以作用任何類型。但是也可以添加一個約束,比如指定一個類型必須采納某協議或者是指定類等。在Swift中(Bool,Int,Doube,String默認都是哈希的),Dictionary的鍵就需要必須是可哈希的,方便字典查找是否已包含某個鍵的值。
類型約束語法
可以在類型參數名后面加一個類型或者協議名,通過冒號隔開,多個類型參數之間用逗號隔開
func somFuntion<C:NSObject, P: NSObjectProtocol>(someClass: C, someProtocol: P){    //這里用NSObject和NSObjectProtocol做例子}
在定義的這個函數中,有兩個類型約束,第一次類型參數C代表是某個類,第二個參數P代表某個協議。

類型約束實踐

這個非泛型類型的方法用來查找某個字符串是否在字符數組中,存在返回index
func findStrInArray(_ array: [String], strToFind: String) -> Int?{    for (index,value) in array.enumerated(){        if strToFind == value{            return index        }    }    return nil}下面這是針對上面非泛型方法泛型版本的方法
func findIndex<T: Equatable> (_ array: [T], _ valueToFind: T) -> Int? {    for  (index,value) in array.enumerated(){        if value == valueToFind { //如果沒指定S:Equatable 這句話會編譯不通過            return index        }    }    return nil}
在這個泛型例子中,不是所有的類型都可以 用 == 來比較的,所有必須指定泛型類型參數的約束為 Swift提供的 Equatable 協議,這表示T代表的類型必須是支持 Equatable 協議的。所有的Swift標準類型默認都是支持Equatable協議的.
let value = findIndex([3.14159, 0.1, 0.25], 9.3)// doubleIndex 類型為 Int?,其值為 nil,因為 9.3 不在數組中let stringIndex = findIndex(["Mike", "Malcolm", "Andrea"], "Andrea")// stringIndex 類型為 Int?,其值為 2

8.關聯類型

在定義協議的時候,有時候用一個或者多個關聯類型作為定義協議的一部分,關聯類型作為協議的一部分,為某個類型提供了一個占位符,其實際類型會在采納的時候被指定。并用關鍵字typealias 關鍵字來指定關聯名

關聯類型實踐

下面定義一個協議,協議指定了一個關聯類型
protocol Container{    associatedtype itemType //聲明一個關聯類型    mutating func appended(item: itemType)    var count: Int{ get }    subscript(i: Int) -> itemType { get }}
下面是非泛型的版本采納 Container 協議
struct intStack: Container {    // IntStack 的原始實現部分    var items = [Int]()    mutating func push(item: Int) {        items.append(item)    }    mutating func pop() -> Int {        return items.removeLast()    }        // Container 協議的實現部分    mutating func appended(item: Int) {        self.push(item: item)    }    var count: Int {        return items.count    }    subscript(i: Int) -> Int {        return items[i]    }}下面是一個泛型版本的
struct genericStack<T>: Container{    // genericStack<T> 的原始實現部分    var items = [T]()    mutating func push(item: T) {        items.append(item)    }    mutating func pop() -> T {        return items.removeLast()    }        // Container 協議的實現部分    mutating func appended(item: T) {        self.push(item: item)    }    var count: Int {        return items.count    }    subscript(i: Int) -> T {        return items[i]    }}

通過擴展一個存在類型來指定關聯類型

通過擴展添加協議的一致性描述了如何利用一個已存在類型符合一個協議,這包括了使用關聯協議
Swift中的Array都滿足了Container協議的要求,意味著可以擴展Array采納Container協議,你可以通過一個空擴展來實現這點.
extension Array :Container{    mutating internal func appended(item: Element) {}}
定義這個擴展之后,可以用Array當做Container類型使用。

9.Where子句

類型約束能夠讓我們為泛型類型添加一些約束和條件。為關聯類型添加一些約束也是很有必要的。可以在參數列表中使用where子句來為關聯類型添加約束。
下面的例子判斷兩個采納Container協議的類型是否所有的元素順序及值都相等。
func allItemsMatch<C1: Container,C2: Container>(someContainer: C1,_ anotherContainer: C2) -> Bool where C1.itemType == C2.itemType, C1.itemType: Equatable {    if someContainer.count != anotherContainer.count {        return false    }    for i in 0...someContainer.count-1{        if someContainer[i] != anotherContainer[i]{            return false        }    }    return true}
這個泛型函數在類型參數里面添加了where子句約束,C1,C2都必須是采納Container協議的類型,并且C1、C2的泛型類型必須相同,而且C1的泛型類型必須是采納Equatable的。
var stackOfStrings = genericStack<String>()stackOfStrings.appended(item: "uno")stackOfStrings.appended(item: "dos")stackOfStrings.appended(item: "tres")var arrayOfStrings = ["uno", "dos", "tres"] //array類型的滿足Container類型,參考上面的extension Arrayif allItemsMatch(stackOfStrings, arrayOfStrings) {    print("All items match.")} else {    print("Not all items match.")}//結果是:All items match.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
狠狠躁天天躁日日躁欧美| 国产精品美女av| 91免费电影网站| 69av在线视频| 裸体女人亚洲精品一区| 久热精品视频在线免费观看| 日韩av理论片| 国产成人激情小视频| 国产精品自产拍在线观看| 国产精品永久在线| 日韩电影大全免费观看2023年上| 久久精品这里热有精品| 亚洲欧美资源在线| 国产精品v片在线观看不卡| 亚洲电影免费观看| 在线视频欧美日韩精品| 国产精品免费电影| 日韩欧美在线观看视频| 日韩最新av在线| 国内成人精品视频| 国产精品成人在线| 亚洲女人初尝黑人巨大| 国产精品久久久久久亚洲影视| 亚洲最大成人在线| 在线观看日韩专区| 色黄久久久久久| 久久精品亚洲精品| 日韩一区二区av| 欧美精品福利在线| 亚洲精品国产品国语在线| 亚洲午夜精品视频| 欧美日韩一区二区免费在线观看| 亚洲一级一级97网| 欧美猛交免费看| 在线观看免费高清视频97| 欧美日韩国产成人高清视频| 欧美激情在线狂野欧美精品| 91免费国产视频| 亚洲美腿欧美激情另类| 国产综合久久久久| 久久久免费av| 亚洲综合自拍一区| 色777狠狠综合秋免鲁丝| 欧美午夜女人视频在线| 国产精品va在线播放我和闺蜜| 成人精品在线视频| 亚洲va久久久噜噜噜久久天堂| 亚洲人成网站在线播| 奇米成人av国产一区二区三区| 69视频在线免费观看| 亚洲视频国产视频| 国产精品爱啪在线线免费观看| 91成人天堂久久成人| 亚洲欧洲在线看| 欧美日产国产成人免费图片| 亚洲尤物视频网| 欧美巨乳在线观看| 亚洲欧美日韩中文在线| 97国产一区二区精品久久呦| 日本精品性网站在线观看| 欧美在线观看日本一区| 美日韩在线视频| 国产亚洲日本欧美韩国| 亚洲无av在线中文字幕| 国产一区二区美女视频| 久久久女人电视剧免费播放下载| 国产精品精品久久久| 中文字幕精品网| 午夜精品久久久久久久白皮肤| 91精品国产91久久久久| 欧美日韩国产一区二区三区| 亚洲国产精品专区久久| 久久全球大尺度高清视频| 国产精品久久久久久久久久久久久久| 久久国产精品久久久久久久久久| 91在线视频免费| 亚洲一区二区黄| 国产精品久久久久久久久久久久久久| 国产精品久久久久久久久粉嫩av| 欧美丰满片xxx777| 日韩中文有码在线视频| 精品国产91久久久久久| 国产精品爱啪在线线免费观看| 亚洲成人久久久| 日韩av免费在线看| 色综合91久久精品中文字幕| 日韩在线视频观看| 久久99久国产精品黄毛片入口| 亚洲国产精品高清久久久| 日韩精品一区二区三区第95| 欧美xxxx综合视频| 欧美性xxxx极品高清hd直播| 欧美激情在线一区| 久久精品91久久久久久再现| 欧美亚洲午夜视频在线观看| 欧美情侣性视频| 国产suv精品一区二区三区88区| 精品久久久久久中文字幕| 日韩国产欧美区| 国产手机视频精品| 久久精品亚洲一区| 日韩在线观看电影| 国产精品欧美激情在线播放| 日韩极品精品视频免费观看| 欧美大片免费观看在线观看网站推荐| 4438全国成人免费| 亚洲欧美日韩精品久久| 91免费人成网站在线观看18| 欧美最猛黑人xxxx黑人猛叫黄| 久久伊人免费视频| 亚洲激情免费观看| 日本aⅴ大伊香蕉精品视频| 日韩av不卡电影| 欧美性理论片在线观看片免费| 国产精品一区二区女厕厕| 欧美日韩国产二区| 亚洲天堂成人在线| 中文字幕国产精品久久| 日本一区二区在线免费播放| 韩日欧美一区二区| 亚洲精品中文字幕av| 亚洲欧洲第一视频| 欧美国产日韩一区二区在线观看| 欧美一级电影免费在线观看| 2019日本中文字幕| 国产成人免费91av在线| 亚洲丝袜一区在线| 亚洲午夜性刺激影院| xvideos亚洲人网站| 国产精品欧美激情在线播放| 欧美日韩中文在线观看| 国内免费久久久久久久久久久| 高清欧美性猛交xxxx黑人猛交| 久久久久久国产精品三级玉女聊斋| 色黄久久久久久| 日韩中文在线中文网在线观看| 777午夜精品福利在线观看| 国产精品中文字幕在线| 国产精品18久久久久久麻辣| 亚洲国产欧美日韩精品| 成人激情视频免费在线| 成人淫片在线看| 欧美激情视频一区| 国产精品久久久av| 欧美日本高清视频| 国产精品久久久久久网站| 亚洲免费视频网站| 欧美午夜精品在线| 日韩在线观看免费全| 最近中文字幕mv在线一区二区三区四区| 久久99久久99精品中文字幕| 亚洲天堂av在线免费观看| 国产免费一区二区三区香蕉精| 欧美成人亚洲成人日韩成人| 97在线看免费观看视频在线观看| 欧美激情一级精品国产| 国产成人久久精品| 亚洲欧洲成视频免费观看| 亚洲精品456在线播放狼人| 欧美另类99xxxxx| 欧美视频专区一二在线观看| 国产精品免费视频久久久| 日韩av日韩在线观看| 91人成网站www|