美文网首页
每天学一点Swift----泛型(二)

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

作者: 冯可乐同学 | 来源:发表于2017-06-16 22:41 被阅读44次

四.类型约束

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

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

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

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

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

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

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

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

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

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

5. Swift的String也遵守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.我们已经知道,程序可以通过扩展让已有类型来遵守指定协议,包括使用空扩展让已有类型(该类型已经实现了协议的各种要求)遵守已有协议的情形。但没有涉及到泛型,实际上,这种用法完全是支持泛型的。例如:Swift的Array结构体已经提供了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

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

{

let count = src.count

for var i=0; i

{

dest.append(sec[i])

}

}

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

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

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

(3)C1的ItemType与C2的ItemType必须相同

(4)ItemType必须遵守Printable协议

相关文章

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

    四.类型约束 1.虽然程序可以对泛型形参传入任何类型,但有时候为泛型形参增加某种特定的约束也是必要的。就像字典,D...

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

    一.泛型的作用 1.泛型是一种非常灵活的语法,泛型允许程序在函数、枚举、结构体、类中定义类型形参,这种类型形参实际...

  • 每天学一点Swift----集合(二)

    三.字典:字典中以key-value的形式保存数据,所以同一个字典中key不能重复。 1.声明字典--两种方式 (...

  • 每天学一点Swift----函数(二)

    三.函数类型 1. Swift的每个函数都有类型的,函数类型由函数的形参列表,返回值类型组成。 2.使用函数类型定...

  • 每天学一点Swift----闭包(二)

    七.闭包表达式 1.调用闭包(使用闭包返回值):闭包的本质是功能更加灵活的代码块,因此完全可以将闭包赋值给变量(联...

  • kotlin 泛型

    一:泛型用法 二:泛型约束

  • 每天学一点Swift----面向对象上(二)

    三.类和结构体 1. Swift的类和结构体高度相似,无论在定义语法上还是在用法上。 2.结构体和类的主要区别是:...

  • 每天学一点Swift----面向对象下(二)

    二.类的构造和析构 1.通过集成后,子类中不仅有父类中的存储属性,还有子类自己的存储属性。子类中的所有存储属性都必...

  • Java泛型(黑马程序员武汉中心)

    Java泛型 一、概述 1、泛型含义 2、泛型好处 3、泛型分类 二、常见的泛型案例 1、泛型方法 A.定义时 B...

  • Java 泛型

    一、泛型使用 1、泛型类 2、泛型函数 二、泛型限定符 1、泛型上限 泛型上限使用 extends 限制 多个限制...

网友评论

      本文标题:每天学一点Swift----泛型(二)

      本文链接:https://www.haomeiwen.com/subject/bhxvqxtx.html