泛型是一种很是领会的语法,让我非常膜拜!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>
{ }
未完善以下:
要求泛型类的子类也带泛型声明
扩展泛型类型
类型约束
关联类型
扩展之后类型来肯定关联类型