Swift入门教程19-泛型

来源:互联网 发布:java程序设计课后答案 编辑:程序博客网 时间:2024/05/17 08:23

原创Blog,转载请注明出处

blog.csdn.net/hello_hwc

一 泛型的定义

  和C++的类似,泛型定义了一种适用于任何类型的,可重用的代码,用一种抽象的方式来实现代码。Swift的Array和Dictionary都是用泛型来实现的,因为Array可以保存String类型的变量,也可以保存Int类型的。

举个例子

func swapTwoInts(inout a: Int, inout b: Int) {    let temporaryA = a    a=b    b = temporaryA}func swapTwoStrings(inout a: String, inout b: String) {        let temporaryA = a        a=b        b = temporaryA}func swapTwoDoubles(inout a: Double, inout b: Double) {        let temporaryA = a        a=b        b = temporaryA}
这是同样的函数结构用来交换两种类型,但是不用泛型的话,我们不得不为每一种类型都定义出对应的函数。十分繁琐。

使用泛型之后,我们只需要这样去定义

func swapTwoValues<T>(inout a: T, inout b: T) { let temporaryA = a    a=b    b = temporaryA}

这里的T是占为类型,就是告诉编译器,这是个通用的类型,在实际运算的时候,会有具体的类型进行替换。占为类型可以作为参数,也可以作为返回值。当然也可以定义多个,例如<T1,T2>

注意:Swift是类型安全的语言,编译器会进行类型检查,如果类型不匹配会报错。


二 类型约束

  在泛型定义中,类型约束十分重要。比如,定义一个泛型对一组数据进行排序,那么这组数据一定要能够比较(大于,等于,小于),如若不然,传入一组数据中既有Int,又有String,Int和String进行排序,明显没有一个合理的规则。

   泛型的约束表示这种类型必须继承某个类,或者实现某些协议。

   语法如下

func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) { // function body goes here}

然后,实现一个使用类型约束来定义泛型的例子。

func findIndex<T: Equatable>(array: T[], valueToFind: T) -> Int? {    for (index, value) in enumerate(array) {            if value == valueToFind {                return index            }    }    return nil}
这里,通过泛型来定义一个在数组中查找指定数据的函数,明显这个类型T要支持==运算符。Equatable就是系统提供的一种协议,遵循这种协议的类型都可以使用==运算符。

三 关联类型

在二中,我们使用了系统提供的Equatable,那么如何自定义类似的协议呢?

使用关联类型,语法是在协议中使用typealise关键字来定义关联类型。

举例

protocol Container {typealias ItemTypemutating func append(item: ItemType) var count: Int { get }subscript(i: Int) -> ItemType { get }}
这里,定义一种关联类型,ItemType,对于协议来说,任何遵循这个协议的结构体必须实现两个方法(append,count)一个下标脚本。而ItemType的具体类型由遵循协议的类来决定。例如

struct IntStack: Container {// IntStack

四 Where语句

Where语句对关联类型进行了更进一步的约束。一个where语句可以让一个关联类型遵循某个特定的协议,也可以让特定的数据类型和关联类型的数据类型一致。

func allItemsMatch<        C1: Container, C2: Container        where C1.ItemType == C2.ItemType, C1.ItemType: Equatable> (someContainer: C1, anotherContainer: C2) -> Bool {        if someContainer.count != anotherContainer.count {            return false        }        for i in 0..<someContainer.count {            if someContainer[i] != anotherContainer[i] {                return false            }        }        return true}

这里定义了四个约束

1.C1必须遵循Container协议

2.C2必须遵循Container协议

3.C1和C2的ItemType一致

4.C1的ItemType遵循Equatable协议




2 0
原创粉丝点击