博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
23.泛型
阅读量:5067 次
发布时间:2019-06-12

本文共 3988 字,大约阅读时间需要 13 分钟。

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

1.泛型所解决的问题

//先看一个示例func swapTwoInts(inout a: Int, inout _ b: Int){    let temporaryA = a;    a = b;    b = temporaryA;}

  上面的函数实现了交换两个 Int 变量的值的功能,但是它只能交换 Int ,如果你想要交换两个 String 值或者 Double值,就不得不写更多的函数。

 2.泛型函数

//问题解决func swapTwoValues
(inout a: T, inout _ b: T){ //swap(&a , &b); //系统的函数,等效于下面三行代码 let temporaryA = a; a = b; b = temporaryA;}//交换Int型var someInt = 3;var anotherInt = 107;swapTwoValues(&someInt, &anotherInt);print("\(someInt), \(anotherInt)");//交换String型var someString = "hello";var anotherString = "world";swapTwoValues(&someString, &anotherString);print("\(someString), \(anotherString)");

3.类型参数

  • 在上面的 例子中,占位类型 T 是类型参数的一个例子。类型参数指定并命名一个占位类型,并且紧随在函数名后面,使用一对尖括号括起来(例如 <T>)。
  • 一旦一个类型参数被指定,你可以用它来定义一个函数的参数类型(例如 swapTwoValues(_:_:) 函数中的参数 a b),或者作为函数的返回类型,还可以用作函数主体中的注释类型。在这些情况下,类型参数会在函数调用时被实际类型所替换。(在上面的 swapTwoValues(_:_:) 例子中,当函数第一次被调用时,T Int 替换,第二次调用时,被 String 替换。)
  • 你可提供多个类型参数,将它们都写在尖括号中,用逗号分开。

4.命名类型参数

  • 在大多数情况下,类型参数具有一个描述性名字,例如 Dictionary<Key, Value> 中的 Key Value,以及 Array<Element> 中的 Element,这可以告诉阅读代码的人这些类型参数和泛型函数之间的关系。然而,当它们之间没有有意义的关系时,通常使用单个字母来命名,例如 TUV。

5.泛型类型

//自定义泛型类型---栈struct Stack
{ var items = [Element](); mutating func push(item: Element) { items.append(item); } mutating func pop() -> Element { return items.removeLast(); }}//String类型的Stackvar stackOfStrings = Stack
();stackOfStrings.push("uno");stackOfStrings.push("dos");stackOfStrings.pop();stackOfStrings.pop();//Int类型的Stackvar stackOfInt = Stack
();stackOfInt.push(3);stackOfInt.pop();

6.扩展一个泛型类型

  • 当你扩展一个泛型类型的时候,你并不需要在扩展的定义中提供类型参数列表。原始类型定义中声明的类型参数列表在扩展中可以直接使用,并且这些来自原始类型中的参数名称会被用作原始定义中类型参数的引用。
struct Stack
{ var items = [Element](); mutating func push(item: Element) { items.append(item); } mutating func pop() -> Element { return items.removeLast(); }}extension Stack{ var topItem: Element? { return items.isEmpty ? nil : items[items.count - 1]; }}var stackOfStrings = Stack
();stackOfStrings.push("uno");if let topItem = stackOfStrings.topItem{ print("The top item on the stack is \(topItem)."); //"The top item on the stack is uno.\n"}

7.类型约束

  • 类型约束可以指定一个类型参数必须继承自指定类,或者符合一个特定的协议或协议组合。

   类型约束语法:

//TODO:类型约束语法 func someFunction
(someT: T, someU: U) { // 这里是泛型函数的函数体部分 }//TODO:字典定义示例 public struct Dictionary
: CollectionType, DictionaryLiteralConvertible { }

  类型约束示例:

func findIndex
(array: [T], _ valueToFind: T) -> Int?{ for (index, value) in array.enumerate() { //如果不对T加类型约束Equatable,这里是不能直接用==进行比较的 if value == valueToFind { return index; } } return nil;}let doubleIndex = findIndex([3.14159, 0.1, 0.25], 9.3);let stringIndex = findIndex(["Mike", "Malcolm", "Andrea"], "Andrea");

8.关联类型

  • 定义一个协议时,有的时候声明一个或多个关联类型作为协议定义的一部分将会非常有用。关联类型为协议中的某个类型提供了一个占位名(或者说别名),其代表的实际类型在协议被采纳时才会被指定。你可以通过 associatedtype 关键字来指定关联类型。
protocol Container{    associatedtype ItemType;        var count: Int { get };    subscript(i: Int) -> ItemType { get };    mutating func append(item: ItemType);}struct Stack
: Container{ // Stack
的原始实现部分 var items = [Element](); mutating func push(item: Element) { items.append(item); } mutating func pop() -> Element { return items.removeLast(); } // Container 协议的实现部分 //这里占位类型参数 Element 被用作 append(_:) 方法的 item 参数和下标的返回类型。Swift 可以据此推断出 Element 的类型即是 ItemType 的类型。因此下面的这句代码可以不加,当然加上也没有问题// typealias ItemType = Element; var count: Int { return items.count; } subscript(i: Int) -> Element { return items[i]; } mutating func append(item: Element) { self.push(item); }}

 

 

 

转载于:https://www.cnblogs.com/LeeGof/p/5682927.html

你可能感兴趣的文章
VC++2012编程演练数据结构《8》回溯法解决迷宫问题
查看>>
第一阶段冲刺06
查看>>
WIN下修改host文件并立即生效
查看>>
十个免费的 Web 压力测试工具
查看>>
ckeditor 粘贴后去除html标签
查看>>
面试题
查看>>
51Nod:活动安排问题之二(贪心)
查看>>
EOS生产区块:解析插件producer_plugin
查看>>
数据库框架的log4j日志配置
查看>>
lintcode-easy-Remove Element
查看>>
mysql 根据地图 坐标 查询 周边景区、酒店
查看>>
mysql重置密码
查看>>
jQuery轮 播的封装
查看>>
一天一道算法题--5.30---递归
查看>>
switchcase的用法
查看>>
React.js 小书 Lesson15 - 实战分析:评论功能(二)
查看>>
Java基础03 构造器与方法重载
查看>>
Redis 主从集群搭建及哨兵模式配置
查看>>
nginx ------反向代理和负载均衡
查看>>
908. Smallest Range I
查看>>