Swift 第十一课泛型

泛型代码可以让你写出根据自我需求定义、适用于任何类型的,灵活且可重用的函数和类
型。它可以让你避免重复的代码,用一种清晰和抽象的方式来表达代码的意图。

你可以创建一个 Int 数组,也可创建一个 String 数组,或者甚至于可
以是任何其他 Swift 的类型数据数组。同样的,你也可以创建存储任何指定类型的字典 (dictionary),而且这些类型可以是没有限制的。
这里是一个标准的,非泛型函数 swapTwoInts,用来交换两个 Int 值:

func swapTwoInts(inout a: Int, inout b: Int) {
let temporaryA = a

a=b

 b = temporaryA
}
swapTwoInts 函数是非常有用的,但是它只能交换 Int 值,如果你想要交换两个 String 或 者 Double,就不得不写更多的函数。

泛型函数可以工作于任何类型,这里是一个上面 swapTwoInts 函数的泛型版本,用于交换
两个值:
func swapTwoValues(inout a: T, inout b: T) {
let temporaryA = a
a=b
b = temporaryA
}

这个函数的泛型版本使用了占位类型名字(通常此情况下用字母 T 来表示)来代替实际类
型名(如 In、String 或 Doubl)。占位类型名没有��示 T 必须是什么类型,但是它��示了 a和b必须是同一类型T,而不管T表示什么类型。只有swapTwoValues函数在每次调 用时所传入的实际类型才能决定 T 所代表的类型。
另外一个不同之处在于这个泛型函数名后面跟着的展位类型名字(T)是用尖括号括起来 的()。这个尖括号告诉 Swift 那个 T 是 swapTwoValues 函数所定义的一个类型。因为
T 是一个占位命名类型,Swift 不会去查找命名为 T 的实际类型。
swapTwoValues 函数除了要求传入的两个任何类型值是同一类型外,也可以作为 swapTwoInts 函数被调用。每次 swapTwoValues 被调用,T 所代表的类型值都会传给函
数。

泛型类型
这里展示了如何写一个非泛型版本的栈,Int 值型的栈:
struct IntStack {
var items = Int
mutating func push(item: Int) {
items.append(item)
}
mutating func pop() -> Int {
return items.removeLast()
}
}

这个结构体在栈中使用一个 Array 性质的 items 存储值。Stack ��供两个方法:push 和 pop,从栈中压进一个值和移除一个值。这些方法标记为可变的,因为他们需要修改(或 转换)结构体的 items 数组。
面所展现的 IntStack 类型只能用于 Int 值,不过,其对于定义一个泛型 Stack 类(可以
处理任何类型值的栈)是非常有用的。

这里是一个相同代码的泛型版本:
struct IntStack {
var items = T
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
}
注意到 Stack 的泛型版本基本上和非泛型版本相同,但是泛型版本的占位类型参数为 T 代
替了实际 Int 类型。这种类型参数包含在一对尖括号里(),紧随在结构体名字后面。

T 定义了一个名为“��种类型 T”的节点��供给后来用。这种将来类型可以在结构体的定义里 任何地方表示为“T”。在这种情况下,T 在如下三个地方被用作节点:
- 创建一个名为 items 的属性,使用空的 T 类型值数组对其进行初始化;
- - 指定一个包含一个参数名为 item 的 push 方法,该参数必须是 T 类型;
- 指定一个 pop 方法的返回值,该返回值将是一个 T 类型值。
类型约束
swapTwoValues 函数和 Stack 类型可以作用于任何类型,不过,有的时候对使用在泛型函 数和泛型类型上的类型强制约束为��种特定类型是非常有用的。类型约束指定了一个必须 继承自指定类的类型参数,或者遵循一个特定的协议或协议构成。
例如,Swift 的 Dictionary 类型对作用于其键的类型做了些限制。在字典的��述中,字典 的键类型必须是可哈希,也就是说,必须有一种方法可以使其是唯一的表示。Dictionary
之所以需要其键是可哈希是为了以便于其检查其是否包含��个特定键的值。如无此需求, Dictionary 即不会告诉是否插入或者替换了��个特定键的值,也不能查找到已经存储在字 典里面的给定键值。

这个需求强制加上一个类型约束作用于 Dictionary 的键上,当然其键类型必须遵循 Hashable 协议(Swift 标准库中定义的一个特定协议)。所有的 Swift 基本类型(如
String,Int, Double 和 Bool)默认都是可哈希。 当你创建自定义泛型类型时,你可以定义你自己的类型约束,当然,这些约束要支持泛型

编程的强力特征中的多数。抽象概念如可哈希具有的类型特征是根据他们概念特征来界定
的,而不是他们的直接类型特征。

你可以写一个在一个类型参数名后面的类型约束,通过冒号分割,来作为类型参数链的一
部分。这种作用于泛型函数的类型约束的基础语法如下所示(和泛型类型的语法相同):

func someFunction

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值