Swift泛型Generics淺析講解
泛型(Generics)
1、泛型可以將類型參數(shù)化,提高代碼復(fù)用率,減少代碼量
func swapValue<T>(_ a: inout T, _ b: inout T) -> Void {
(a, b) = (b, a)
}var fn: (inout Int, inout Int) -> () = swapValue
棧
class Stack<E> {
var elements = [E]()
func push(_ element: E) -> Void {
elements.append(element)
}
func pop() -> E {
elements.removeLast()
}
func top() -> E {
elements.last!
}
func size() -> Int {
elements.count
}
}
var intStack = Stack<Int>()
var stringStack = Stack<String>()
var anyStack = Stack<Any>()class SubStack<E>: Stack<E> {
}
struct Stack<E> {
var elements = [E]()
mutating func push(_ element: E) {
elements.append(element)
}
mutating func pop() -> E {
elements.removeLast()
}
func top() -> E {
elements.last!
}
func size() -> Int {
elements.count
}
}匯編分析泛型的實(shí)現(xiàn)原理


通過匯編我們可以看到兩次調(diào)用的swapValues方法的地址是相同的,也就是說是相同的方法,匯編中有關(guān)于metadata的信息,所以推測(cè)Swift中的泛型是通過對(duì)元數(shù)據(jù)的處理實(shí)現(xiàn)的。
關(guān)聯(lián)類型(Associated Type)
1、關(guān)聯(lián)類型的作用:給協(xié)議中用到的類型定義一個(gè)占位名稱
2、協(xié)議中可以擁有多個(gè)關(guān)聯(lián)類型
protocol Stackable {
associatedtype Element
mutating func push(_ element: Element)
mutating func pop() -> Element
func top() -> Element
func size() -> Int
}class StringStack: Stackable {
// typealias Element = String 可寫可不寫
var elements = [String]()
func push(_ element: String) -> Void {
elements.append(element)
}
func pop() -> String {
elements.removeLast()
}
func top() -> String {
elements.last!
}
func size() -> Int {
elements.count
}
}類型約束
protocol Runnable {}
class Person {}
func swapValues<T: Person & Runnable>(_ a: inout T, _ b: inout T) -> Void {
(a, b) = (b, a)
}更多的約束
func equal<S1: Stackable, S2: Stackable>(_ s1: S1, _ s2: S2) -> Bool
where S1.Element == S2.Element, S1.Element: Hashable
{
return false
}協(xié)議類型的注意點(diǎn)
protocol Runnable {}
class Person: Runnable {}
class Car: Runnable {}
func getObject(_ type: Int) -> Runnable {
if type == 0 {
return Person()
}
return Car()
}
var r1 = getObject(0)
var r2 = getObject(1)1、如果協(xié)議中有associatedtype,那么會(huì)有類型識(shí)別不了的問題,以下代碼會(huì)報(bào)錯(cuò)
protocol Runnable {
associatedtype Speed
var speed: Speed {
get
}
}
class Person: Runnable {
var speed: Double {
0.0
}
}
class Car: Runnable {
var speed: Int {
0
}
}
func getObject(_ type: Int) -> Runnable {
if type == 0 {
return Person()
}
return Car()
}泛型解決
解決方案1:使用泛型
protocol Runnable {
associatedtype Speed
var speed: Speed {
get
}
}
class Person: Runnable {
var speed: Double {
0.0
}
}
class Car: Runnable {
var speed: Int {
0
}
}
func getObject<T: Runnable>(_ type: Int) -> T {
if type == 0 {
return Person() as! T
}
return Car() as! T
}
var r1: Person = getObject(0)
var r2: Car = getObject(1)不透明類型(Opaque Type)
1、解決方案2:使用some關(guān)鍵字聲明一個(gè)不透明類型
func getObject(_ type: Int) -> some Runnable {
return Car()
}2、some限制只能返回一種類型
some
1、some除了用在返回值類型上,一般還可以用在屬性類型上
protocol Runnable {
associatedtype Speed
}
class Dog: Runnable {
typealias Speed = Double
}
class Person {
var pet: some Runnable {
return Dog()
}
}到此這篇關(guān)于Swift泛型Generics淺析講解的文章就介紹到這了,更多相關(guān)Swift Generics內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
swift 3.0 正則表達(dá)式查找/替換字符的實(shí)現(xiàn)代碼
正則表達(dá)式使用單個(gè)字符串來描述、匹配一系列符合某個(gè)句法規(guī)則的字符串。本文重點(diǎn)給大家介紹swift 3.0 正則表達(dá)式查找/替換字符的實(shí)現(xiàn)代碼,需要的朋友參考下吧2017-08-08
Swift實(shí)現(xiàn)多個(gè)TableView側(cè)滑與切換效果
這篇文章主要為大家詳細(xì)介紹了Swift實(shí)現(xiàn)多個(gè)TableView側(cè)滑與切換效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
swift中defer的實(shí)際應(yīng)用小結(jié)
這篇文章主要給大家介紹了關(guān)于swift中defer的實(shí)際應(yīng)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
在Mac OS的終端中運(yùn)行Swift應(yīng)用的方法
這篇文章主要介紹了在Mac OS的終端中運(yùn)行Swift應(yīng)用的方法,依靠Xcode的REPL功能來實(shí)現(xiàn),需要的朋友可以參考下2015-07-07
Swift使用enum抹平數(shù)組元素差異實(shí)例詳解
這篇文章主要為大家介紹了Swift使用enum抹平數(shù)組元素差異實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11

