首页 > 代码库 > swift 笔记 (二十) —— 泛型

swift 笔记 (二十) —— 泛型

泛型

泛型是为了解决在针对不同数据类型,而做了同一种功能的操作导致的每个类型我们都要写一份代码的问题。 有了泛型,我们可以只写一份逻辑代码,而适应于不同的数据类型。

func swapInt(inout num1:Int, inout num2: Int) {
     var tmp = num1
     num1 = num2
     num2 = tmp
}

func swapDouble(inout num1: Double, inout num2:Double) {
     var tmp = num1
     num1 = num2
     num2 = tmp 
}

上面两个函数的功能,完全一样,仅仅是数据类型的不同。
所以这种问题,我们可以用泛型来解决:

func swap<T>(inout num1:T, inout num2: T)  {
     var tmp = num1
     num1 = num2
     num2 = tmp 
}

现在只要使用swap这个函数,两个参数的类型相同,就可以交换两个变量的值了。

早些时候,我们已经见过:
var myArray:Array<Int> = [1,2,3,4]
这样的写法了,Array就是个泛型的struct版本,而<>中指定的是我们需要往Array中存放的是什么数据类型。这就是泛型的一种特化方式。

类型约束
有时候,我们需要为泛型的参数做个过滤,有一些参数不准传入,有一些可以。我们就可以通过类型约束来达到这个目的。
<T: 约束>

func isTheSameValue<T: Equatable>(value1: T, value2: T) -> Bool {
    
return value1 == value2
}


所有的支持 == 操作符的类型,都可以当做参数传入。

关联类型
官方的例子:


typealias定义了一个关联类型 ItemType,和三个要求(一个append方法,一个count属性,一个下标)。
协议的实现:


因为swift是会自动推导类型的,所以,这里的typealias ItemType = Int其实是可以省略的。
如果我们需要让一个已经存在的类也符合这个关联类型,而,这个类,又恰好已经遵循了这个协议,我们就可以留个空扩展,让它满足我们的需求:
extension Array: Containner {}

这样就可以将任何Array当作是Containner来使用了。

Where 语句

官方的例子:


where语句写在泛型的类型参数列表中,以约束两个以上的类型,据有某些共同特质,才可以传入allItemsMatch这个函数。

这个where语句描述的要求是:
C1 C2 是两个参数的类型,他们都遵循Container约束,C1的ItemType与C2的ItemType必须相同,并且C1的Itemtype是遵循Equatable协议的(既然C2的ItemType与C1的ItemType必须相同,所以这里不必再单独写个C2的ItemType也符合Equatable)。

函数体就不解释了,肯定看得懂。