系统整理 精讲 swift 泛型

来源:互联网 时间:1970-01-01

泛型是一种非常领会的语法,让我很是膜拜!

真是让人又爱又恨,学不懂的时候很抓狂

允许程序在函数,枚举,结构体,类中定义类型形参(类型可以动态改变)

每次使用可以传入不同类型的形参!

Array<T>   T就是泛型,代表数组元素的类型

struct Dictionary《Key:Hashable,Value》 key value是泛型语法

Array<String>限定了元素类型 位String的数组

为什么要用?会带来哪些方便?请看下面例子

要求:前一个数组追加到后一个数组中

func copyIntArray(src:[Int],inout dest:[Int])

{

// 遍历 并加到数组后边

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>

{ }

未完善如下:

要求泛型类的子类也带泛型声明

扩展泛型类型

类型约束

关联类型

扩展以后类型来确定关联类型


相关阅读:
Top