每天学一点Swift----泛型(二)

43 篇文章 0 订阅
42 篇文章 0 订阅

.类型约束

1. 虽然程序可以对泛型形参传入任何类型,但有时候为泛型形参增加某种特定的约束也是必要的。就像字典,Dictionarykey的类型也是通过泛型形参来表示的,但Dictionary并不允许任意一种类型的数据都能作为key,只有实现了Hashable协议的类型才能作为key。这就是一种类型约束。


2. 类型约束就是指定义类型参数时增加一个限制,约束这种类型参数必须继承指定的类,或遵守一个特定的协议或合成协议。


3. 例如,定义了一个函数实现了对整数进行冒泡排序,当对DoubleString类型进行比较是就需要到泛型了,但是又有另一个问题:能排序的数组元素必须是可比较大小的,否则程序无法对数组元素进行排序。也就是说,数组元素必须实现Comparable协议,这就需要使用类型约束了。


4. 定义泛型时使用类型约束的语法格式如下:

   <类型形参1父类,类型形参2:协议,类型形参3 protocol<协议1协议2> ...>

上面给出了3种形式的类型约束:

1)类型形参1:实际传给该形参的类型必须继承指定父类

2)类型形参2:实际传给该形参的类型必须遵守指定协议

3)类型形参3:实际传给该形参的类型必须同时遵守合成协议的协议1,协议2

实际中具体需要定义多少个类型形参,完全取决于程序的需要。


5. SwiftString也遵守Comparable协议,因袭String也是可以比较大小的,Swift比较String的大小时按各字符对应的Unicode码进行比较。


.关联类型

1. 定义协议时,也允许定义一个或多个类型参数,这种类型参数本质上也属于泛型,但需要以关联类型(Associated Type)的形式进行声明。协议中的类型形参需要等到协议被实现时才会确定下来。


2. 在协议中以typealias关键字来声明关联类型。


3. 举个栗子:

protocol Container

{

   //声明类型形参,该类型形参需要等到协议被实现时才能确定下来

   typealias ItemType

   //向容器中添加一个元素

   mutating func append(item : ItemType)

   //获取容器中元素的个数

   var count : Int{}

   //根据索引来获取元素

   subscript(i : Int) -> ItemType {get}

}

上面程序中,正因为Container协议使用了类型形参,这个类型形参到底代表什么类型,必须等到实现该协议时才能确定下来,这使得该容器可以装任意类型的数据。这就要按实现者要指定什么类型了,例如:

struct IntList : Container 

{

   //显式指定ItemType类型代表Int类型

   typealias ItemType = Int

   ...

}


4. 我们已经知道,程序可以通过扩展让已有类型来遵守指定协议,包括使用空扩展让已有类型(该类型已经实现了协议的各种要求)遵守已有协议的情形。但没有涉及到泛型,实际上,这种用法完全是支持泛型的。例如:SwiftArray结构体已经提供了append(newEleme T)方法,count属性,因此程序也可以通过扩展让Array实现Container协议:extension Array Contaioner{}。这样Array结构体就实现了Container协议,因此Array也可以当成Container使用。


5. 如果程序只需要简单地定义类型形参必须是某个类的子类,或者必须遵守某个协议,使用类型约束即可。如果程序需要对类型形参进行更多复杂的约束,就需要借助于where字句了。


6. where字句也属于泛型声明的一部分,where字句可以指定一个条件表达式,该条件表达式用于对类型形参增加更多额外的限制。在泛型声明中使用where字句的语法如下:

<类型形参父类型,类型形参2协议, ... where条件>


7举个栗子,下面将会定义一个copyContainer函数,这个函数用于将前一个Container中的元素复制到另一个Container中,此时就要求两个Container中的ItemType必须相等,另外,还加了Container容器包含的元素必须是可以打印的要求。

func copyContainer <C1 : Container, C2 : Container

      where C1.ItemType == C2.ItemType, C1.ItemType : Printable>(src : C1, inout dest : C2)

{

   let count = src.count

   for var i=0; i<count; i++

   {

dest.append(sec[i])

   }

}

上面代码中泛型声明一共有4个要求:

1C1类型形参必须遵守Container协议

2C2类型形参必须遵守Container协议

3C1ItemTypeC2ItemType必须相同

4ItemType必须遵守Printable协议


上一篇:每天学一点Swift----泛型(二)

下一篇:每天学一点Swift---- 运算符函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值