泛型是一種很是領會的語法,讓我非常膜拜!php
真是讓人又愛又恨,學不懂的時候很抓狂swift
容許程序在函數,枚舉,結構體,類中定義類型形參(類型能夠動態改變)數組
每次使用能夠傳入不一樣類型的形參!閉包
Array<T> T就是泛型,表明數組元素的類型app
struct Dictionary《Key:Hashable,Value》 key value是泛型語法函數
Array<String>限定了元素類型 位String的數組post
爲何要用?會帶來哪些方便?請看下面例子ui
要求:前一個數組追加到後一個數組中spa
func copyIntArray(src:[Int],inout dest:[Int])element
{
// 遍歷 並加到數組後邊
for element in src{
dest.append(element)
}
}
使用
var arr = [2,5]
copyIntArray([12,9],&arr)
println(arr) // [2,5,12,9]
那麼再要求讓你實現添加字符串呢,好吧重寫一個
func copyStringArray(src:[String],inout dest:[String])
{
for element in src{
dest.append(element)
}
}
使用
var strArr = ["oc","swift"]
copyStringArray(["php",&strArr])
你們發現了吧,除了類型之外,其餘代碼都同樣的,爲何重複造輪子?合二爲一吧。假如還有Double類型呢?
泛型派上用場了
泛型函數:指定一個或多個類型佔位符,類型暫時不肯定,等具體調用的時候再肯定
func copyArray<T>(src:[T],inout dest:[T])
{
for element in src
{
dest.append(element)
}
}
看到如此強大了吧?
而後隨意使用
var arr = [5,8]
copyArray([9,58],&arr)
var strArr = ["renhairui","hello"]
copyArray(["nihao",&strArr])
var doubleArr = [1.2,3.4]
copyArray([6.5,1.0],&doubleArr)
T是類型佔位符,能夠當成普通類型使用
經過泛型,讓函數具備更好的適應性
下邊來深刻一下:定義多個類型參數
要求:投影運算, 數組類型不肯定,怎麼投影不肯定,返回值類型不肯定
先定義兩個類型參數
SrcType 表明須要執行投影數組的元素類型
DscType 獲得的元素類型
func projection<SrcType,DescType>(src:[SrcType],fn:(SrcType)->DescType)->[DescType]
{
var result = [DescType]
for element in src
{
// 使用fn函數對數組元素進行投影運算,將運算結果添加到result數組中
result.append(fn(element))
}
}
使用
var books = ["任海瑞","iOS","engineer"]
使用尾隨閉包
var proj1 = projection(books){
countElements($0) //計算元素長度
}
println(proj1) // [3,3,8]
假如
var proj2 = projection(books){
"<"+$0+">"
}
println(proj2) //["<任海瑞>","<iOS>","<engineer>"]
再如
books = ["PHP","iOS","swift"]
var proj3 = projection(books){
(b:String)->(String,String) in
return (b,"任海瑞")
}
println(proj3) //["PHP,任海瑞","iOS,任海瑞","swift,任海瑞"]
另外也能夠改變 books 的類型,任意類型。
定義泛型類型
struct Rect<T>
{
var x:T
var y:T
var width:T
var height:T
// 計算屬性
var position:(T,T)
{
return (self.x,self.y)
}
}
使用
let rect = Rect<Double>(x:1.2,y3.4,width:8.5,height:7.8)
let (x,y) = rect.position
println("\(x),\(y)")
let rect2 = Rect<Int>(x:3,y:6,width:10,height:30)
let(x,y) = rect.postion
class Apple<T>
{
var info:T
init(info:T)
{
self.info = info
}
}
使用
var a1= Apple<String>(info:"蘋果")
println(a1.info)
var a2 = Apple<Double>(info:5.6)
從泛型類派生出子類
class A:Apple<T>
{ }
未完善以下:
要求泛型類的子類也帶泛型聲明
擴展泛型類型
類型約束
關聯類型
擴展之後類型來肯定關聯類型