Swift進階之泛型

swift-generic.jpg

泛型Generic在swift中非常重要,它提升了代碼的通用性和簡潔性努释,很多開源的組件都是通過泛型來實現(xiàn)。泛型是什么呢伐蒂?字面意思大概就是寬泛的類型,在swift中泛型非常靈活汰翠,涉及到的概念也相對較多昭雌,筆者寫下這篇文章做一個小小的總結(jié),有疏漏的地方以后會慢慢補全烛卧。讀者朋友可以在文章底部,找到參考鏈接呈宇。

1. 寫一個泛型函數(shù)



func addInts(x: Int, y: Int) -> Int {
    return x + y
}

let intSum = addInts(x: 1, y: 2)
print(intSum)

func addDoubles(x: Double, y: Double) -> Double {
    return x + y
}


func add1<T>(x: T, y: T) {
  return x + y
}

2. 標準庫中的泛型引用

在swift中局雄,標準庫Array, Dictionary, Optional都是基于泛型實現(xiàn)的,按住鍵盤的option按鍵蜈漓,鼠標點擊下面的數(shù)組和字典變量,即可看到該變量是泛型類型宫盔,

let numbers = [1, 2, 3]
let firstNumber = numbers[0]


var numbersAagin: Array<Int> = []
numbersAagin.append(1)
numbersAagin.append(2)
numbersAagin.append(3)
//numbers.append("All hail load")



let countryCodes = ["Arendelle": "AR", "Genovia":"GN", "Freedonia": "FD"]
let countryCode = countryCodes["Freedonia"]


let optionalName = Optional<String>.some("Princess Moana")
if let name = optionalName {
    print(name)
}

3. 泛型類型

通過構(gòu)造一個泛型隊列Queue灼芭,來簡單介紹泛型類型,如下代碼所示彼绷,


struct Queue<Element> {
    fileprivate var elements: [Element] = []
    mutating func enqueue(newElement: Element) {
        elements.append(newElement)
    }
    
    mutating func dequeue() -> Element? {
        guard !elements.isEmpty else { return nil }
        return elements.remove(at: 0)
    }
}


var q = Queue<Int>()
q.enqueue(newElement: 4)
q.enqueue(newElement: 2)

print(q.dequeue())
print(q.dequeue())
print(q.dequeue())

在swift中定義class, struct, enum時,都可以通過泛型來進行定義句狼,現(xiàn)在定義一個泛型結(jié)構(gòu)體SquareMartrix热某,它表示一個n * n的矩陣胳螟,定義如下筹吐,

struct SquareMatrix<T> {
    var backingArray: [T] = []
    let size: Int
    func itemAt(row: Int, column: Int) -> T {
        return ...
    }
    
    init(size: Int, initial: T) {
        self.size = size
        backingArray = Array(repeating: initial, count: size * size)
    }
}

let a = SquareMatrix(size: 10, initial: 50)
let b : SquareMatrix<String?> = SquareMatrix(size: 5, initial: nil)

因為SquareMatrix是通過泛型定義,所以可以存放Int和String內(nèi)容嘉竟。

4. 泛型函數(shù)

下面的泛型函數(shù)洋侨,將字典內(nèi)容轉(zhuǎn)換為元組數(shù)組,


func pairs<Key, Value>(from dictionary: [Key: Value]) -> [(Key, Value)] {
    return Array(dictionary)
}

let somePairs = pairs(from: ["mininum": 199, "maxinum": 299])
print(somePairs)

let morePairs = pairs(from: [1: "swift", 2: "Generics", 3: "Rule"])
print(morePairs)

5. 泛型約束


func middle<T: Comparable>(array: [T]) -> T? {
    guard !array.isEmpty else { return nil }
    return array.sorted()[(array.count-1) / 2]
}

middle(array: [2, 5, 1, 3, 4])


protocol Summable {
    static func +(lhs: Self, rhs: Self) -> Self
}

extension Int: Summable {
    
}

extension Double: Summable {
    
}


func add2<T: Summable>(x: T, y: T) -> T {
    return x + y
}

let addIntSum = add2(x: 1, y: 2)
print(addIntSum)

let addDoubleSum = add2(x: 10.0, y: 14.0)
print(addDoubleSum)


extension String: Summable {
    
}

let addString = add2(x: "Generics", y: "Are awesome!")
print(addString)

6. 擴展泛型類型

在swift中通過extension來進行擴展边苹,如下代碼所示裁僧,為Queue擴展一個peek方法聊疲,該方法返回隊列中的第一個元素,


extension Queue {
    func peek() -> Element? {
        return elements.first
    }
}

7. 繼承泛型類型


class Box<T> {
    
}

class Gift<T>: Box<T> {
    func wrap() {
        
    }
}

class Rose {
    
}

class ValentinesBox: Gift<Rose> {
    override func wrap() {
        print("wrap with love paper")
    }
}

class Shoe {
    
}

class GlassSlipper: Shoe {
    
}

class ShoeBox: Box<Shoe> {
    
}

let box = Box<Rose>()
let gift = Gift<Rose>()
let shoeBox = ShoeBox()

let valentines = ValentinesBox()
gift.wrap()

8. 泛型定義枚舉的關(guān)聯(lián)值


enum Result<Value> {
    case success(Value)
    case failure(Error)
}

enum MathError: Error {
    case divisionByZero
}

func divide(_ x: Int, by y: Int) -> Result<Int> {
    guard y != 0 else { return .failure(MathError.divisionByZero) }
    return .success(x / y)
}

9. 在協(xié)議中使用關(guān)聯(lián)類型associatedType作為泛型

在Protocol中不能使用泛型阱表,但可以使用associatedType來替代泛型贡珊,如下代碼所示,


protocol Animal {
    associatedtype Food
    func eat(food: Food)
}

struct Cow: Animal {
    typealias Food = String
    func eat(food: Food) {
        print("my food can be any string")
    }
}

let cow = Cow()
cow.eat(food: "corn")

struct Chicken: Animal {
    enum Food: String {
        case grass, corn
    }
    
    func eat(food: Food) {
        switch food {
        case .grass:
            print("My food is a grass enum")
        case .corn:
            print("my food is a corn enum")
        }
    }
}

let chicken = Chicken()
chicken.eat(food: .grass)

struct Dog: Animal {
    typealias Food = [String]
    func eat(food: Food) {
        food.forEach { print("I am eating an array of food, current is \($0)") }
    }
}

let dog = Dog()
dog.eat(food: ["cake", "treat", "bone"])

參考鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谨胞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子胯努,更是在濱河造成了極大的恐慌,老刑警劉巖蒲讯,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灰署,死亡現(xiàn)場離奇詭異局嘁,居然都是意外死亡晦墙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門但指,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抗楔,“玉大人,你說我怎么就攤上這事连躏。” “怎么了卢肃?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵才顿,是天一觀的道長。 經(jīng)常有香客問我幅垮,道長尾组,這世上最難降的妖魔是什么忙芒? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任讳侨,我火速辦了婚禮,結(jié)果婚禮上跨跨,老公的妹妹穿的比我還像新娘。我一直安慰自己忱嘹,他們只是感情好耕渴,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著础米,像睡著了一般分苇。 火紅的嫁衣襯著肌膚如雪椭盏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天糟红,我揣著相機與錄音乌叶,去河邊找鬼。 笑死事扭,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的求橄。 我是一名探鬼主播葡公,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼涵亏!你這毒婦竟也來了蒲凶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤宠默,失蹤者是張志新(化名)和其女友劉穎灵巧,沒想到半個月后光稼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體孩等,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡肄方,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年蹬癌,在試婚紗的時候發(fā)現(xiàn)自己被綠了虹茶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隅要。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖要门,靈堂內(nèi)的尸體忽然破棺而出廓啊,到底是詐尸還是另有隱情欢搜,我是刑警寧澤谴轮,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布第步,位于F島的核電站疮装,受9級特大地震影響粘都,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜受啥,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一鸽心、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧顽频,春花似錦、人聲如沸嘁圈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怠惶。三九已至,卻和暖如春脓魏,著一層夾襖步出監(jiān)牢的瞬間兰吟,已是汗流浹背茂翔。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工珊燎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人俐末。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像载矿,于是被迫代替她去往敵國和親烹卒。 傳聞我的和親對象是個殘疾皇子闷盔,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容