16-泛型

泛型(Generics)

  • 泛型可以將類型參數(shù)化疙挺,提高代碼復(fù)用率,減少代碼量
func swapValues<T>(_ a: inout T, _ b: inout T) {
     (a, b) = (b, a)                                              
} 
var i1 = 10
var i2 = 20
swapValues(&i1, &i2)

var d1 = 10.0
var d2 = 20.0
swapValues(&d1, &d2)

struct Date {
 var year = 0, month = 0, day = 0                                            
}

var dd1 = Date(year: 2011, month: 9, day: 10) 
var dd2 = Date(year: 2012, month: 10, day: 11) 
swapValues(&dd1, &dd2) 
  • 泛型函數(shù)賦值給變量
func test<T1, T2>(_ t1: T1, _ t2: T2) {} 
var fn: (Int, Double) -> () = test 

泛型

class Stack<E> {
   var elements = [E]()
   func push(_ element: E) { elements.append(element) } func pop() -> E { elements.removeLast() }
   func top() -> E { elements.last! }
   func size() -> Int { elements.count } 
} 
class SubStack<E> : Stack<E> {} 

\color{green}{相當(dāng)于修改結(jié)構(gòu)體內(nèi)存布局榜聂,需要加 mutating}

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 }                                          
} 
var stack = Stack<Int>()
stack.push(11)
stack.push(22)
stack.push(33)
print(stack.top()) // 33
print(stack.pop()) // 33
print(stack.pop()) // 22
print(stack.pop()) // 11
print(stack.size()) // 0
enum Score<T> {
    case point(T)
    case grade(String)
}
let score0 = Score<Int>.point(100) 
let score1 = Score.point(99)
let score2 = Score.point(99.5) 
let score3 = Score<Int>.grade("A") 

泛型的本質(zhì):

  • c++代碼本質(zhì) 根據(jù)類型創(chuàng)建多個(gè)棚亩。
func swapValues<T>(_ a: inout T, _ b: inout T) {
     (a, b) = (b, a)                                              
} 

func swapValues<Int>(_ a: inout Int, _ b: inout Int) {
     (a, b) = (b, a)                                              
} 

func swapValues<Double>(_ a: inout Double, _ b: inout Double) {
     (a, b) = (b, a)                                              
} 
  • 看下swift


    image.png

    image.png

    image.png

不同的類型胧瓜,函數(shù)地址一樣。metadata源類型身害∧可以自研下。

關(guān)聯(lián)類型(Associated Type)

  • 關(guān)聯(lián)類型的作用:給協(xié)議中用到的類型定義一個(gè)占位名稱

  • 協(xié)議中可以擁有多個(gè)關(guān)聯(lián)類型

protocol Stackable {
   associatedtype Element // 關(guān)聯(lián)類型 
   mutating func push(_ element: Element) 
   mutating func pop() -> Element
   func top() -> Element
   func size() -> Int                                 
} 
class Stack<E> : Stackable {
    // typealias Element = E
    var elements = [E]()
    func push(_ element: E) {                                     
        elements.append(element) 
    } 

    func pop() -> E { elements.removeLast() } 
    func top() -> E { elements.last! }
    func size() -> Int { elements.count } 
}
class StringStack : Stackable {
    // 給關(guān)聯(lián)類型設(shè)定真實(shí)類型
    // typealias Element = String
    var elements = [String]()
    func push(_ element: String) { elements.append(element) } func pop() -> String { elements.removeLast() }                                          
    func top() -> String { elements.last! } 
    func size() -> Int { elements.count } }      
} 

var ss = StringStack()
ss.push("Jack")
ss.push("Rose")

類型約束

protocol Runnable { }
class Person { }
func swapValues<T : Person & Runnable>(_ a: inout T, _ b: inout T) { 
    (a, b) = (b, a)
}
protocol Stackable {
     associatedtype Element: Equatable                                             
}
class Stack<E : Equatable> : Stackable { typealias Element = E } 
func equal<S1: Stackable, S2: Stackable>(_ s1: S1, _ s2: S2) -> Bool 
    where S1.Element == S2.Element, S1.Element : Hashable {
     return false                                   
} 
var stack1 = Stack<Int>()
 var stack2 = Stack<String>()
 // error: requires the types 'Int' and 'String' be equivalent equal(stack1, stack2) 

協(xié)議類型的注意點(diǎn)

protocol Runnable {}
class Person : Runnable {}
class Car : Runnable {}

func get(_ type: Int) -> Runnable { 
    if type == 0 { 
        return Person()
    }
    return Car()
}
var r1 = get(0)
var r2 = get(1)
  • 如果協(xié)議中有associatedtype
protocol Runnable {
   associatedtype Speed
   var speed: Speed { get }
}
class Person : Runnable {
   var speed: Double { 0.0 }
}
class Car : Runnable {
   var speed: Int { 0 }
} 
image.png
image.png

泛型解決

  • 解決方案1:使用泛型
func get<T : Runnable>(_ type: Int) -> T {
  if type == 0 {
     return Person() as! T
  }
  return Car() as! T
}
var r1: Person = get(0)
var r2: Car = get(1)

不透明類型(Opaque Type)

  • 解決方案2:使用some關(guān)鍵字聲明一個(gè)不透明類型
func get(_ type: Int) -> some Runnable { Car() }
var r1 = get(0)
var r2 = get(1)
  • some限制只能返回一種類型
image.png

some

  • some除了用在返回值類型上郎仆,一般還可以用在屬性類型上
protocol Runnable { associatedtype Speed }
class Dog : Runnable { typealias Speed = Double }
class Person {
   var pet: some Runnable {
     return Dog() 
   } 
} 

可選項(xiàng)的本質(zhì)

  • 可選項(xiàng)的本質(zhì)是enum類型
public enum Optional<Wrapped> : ExpressibleByNilLiteral { 
    case none                                              
    case some(Wrapped)
    public init(_ some: Wrapped)                                               
} 
var age: Int? = 10
var age0: Optional<Int> = Optional<Int>.some(10) var age1: Optional = .some(10)
var age2 = Optional.some(10)
var age3 = Optional(10)
age = nil
age3 = .none 
var age: Int? = nil
var age0 = Optional<Int>.none 
var age1: Optional<Int> = .none 
var age: Int? = .none
age = 10
age = .some(20)
age = nil
switch age {
case let v?:
    print("some", v)
case nil:
    print("none")
}
switch age {
case let .some(v):
    print("some", v)
case .none:
    print("none")
}

可選項(xiàng)的本質(zhì)

var age_: Int? = 10
var age: Int?? = age_
age = nil

var age0 = Optional.some(Optional.some(10)) age0 = .none
var age1: Optional<Optional> = .some(.some(10)) age1 = .none 
var age: Int?? = 10
var age0: Optional<Optional> = 10 
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末闻镶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子丸升,更是在濱河造成了極大的恐慌铆农,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狡耻,死亡現(xiàn)場(chǎng)離奇詭異墩剖,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)夷狰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門岭皂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人沼头,你說(shuō)我怎么就攤上這事爷绘。” “怎么了进倍?”我有些...
    開(kāi)封第一講書人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵土至,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我猾昆,道長(zhǎng)陶因,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任垂蜗,我火速辦了婚禮楷扬,結(jié)果婚禮上解幽,老公的妹妹穿的比我還像新娘。我一直安慰自己烘苹,他們只是感情好躲株,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著镣衡,像睡著了一般徘溢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捆探,一...
    開(kāi)封第一講書人閱讀 48,954評(píng)論 1 283
  • 那天然爆,我揣著相機(jī)與錄音,去河邊找鬼黍图。 笑死曾雕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的助被。 我是一名探鬼主播剖张,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼揩环!你這毒婦竟也來(lái)了搔弄?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤丰滑,失蹤者是張志新(化名)和其女友劉穎顾犹,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體褒墨,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炫刷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了郁妈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浑玛。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖噩咪,靈堂內(nèi)的尸體忽然破棺而出顾彰,到底是詐尸還是另有隱情,我是刑警寧澤胃碾,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布涨享,位于F島的核電站,受9級(jí)特大地震影響书在,放射性物質(zhì)發(fā)生泄漏灰伟。R本人自食惡果不足惜拆又,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一儒旬、第九天 我趴在偏房一處隱蔽的房頂上張望栏账。 院中可真熱鬧,春花似錦栈源、人聲如沸挡爵。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)茶鹃。三九已至,卻和暖如春艰亮,著一層夾襖步出監(jiān)牢的瞬間闭翩,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工迄埃, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疗韵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓侄非,卻偏偏與公主長(zhǎng)得像蕉汪,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子逞怨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

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

  • 泛型(Generics) 泛型函數(shù) 泛型可以將類型參數(shù)化者疤,提高代碼復(fù)用率,減少代碼量 T代表 不確定類型參數(shù) 泛型...
    codeTao閱讀 383評(píng)論 1 1
  • 1.泛型 泛型可以將類型參數(shù)化叠赦,提高代碼復(fù)用率驹马,減少代碼量 2.泛型函數(shù)賦值給變量 3.關(guān)聯(lián)類型(Associat...
    一抹相思淚成雨閱讀 173評(píng)論 0 1
  • 泛型(Generics) 泛型可以將類型參數(shù)化,提高代碼復(fù)用率除秀,減少代碼量下面我們來(lái)看一個(gè)經(jīng)典的例子窥翩,a b交換,...
    Jax_YD閱讀 330評(píng)論 0 1
  • 一仗岸、錯(cuò)誤處理 1.1、錯(cuò)誤類型語(yǔ)法錯(cuò)誤(編譯報(bào)錯(cuò))邏輯錯(cuò)誤運(yùn)行時(shí)錯(cuò)誤(可能會(huì)導(dǎo)致閃退借笙,一般也叫做異常) 1.2扒怖、自...
    IIronMan閱讀 627評(píng)論 0 2
  • 泛型(Generics) 泛型可以將類型參數(shù)化,提高代碼復(fù)用率业稼,減少代碼量 泛型函數(shù)賦值給變量 關(guān)聯(lián)類型(Asso...
    Stago閱讀 175評(píng)論 0 0