//泛型(Generics)

import UIKit

/*泛型(Generics):泛型代码可以让你编写适用自定义需求以及任意类型的灵活可重用的函数和类型。它的可以让你避免重复的代码,用一种清晰和抽象的方式来表达代码的意图

类型参数:func swapTwoValues<T,B>(a:T, b:T)->T{ var c:T, var d:B ...}

1.类型参数指定并命名一个占位类型,并且紧随在函数名后面,使用一对尖括号括起来,首字母大写

2.一旦一个类型参数被指定,你可以用它来定义一个函数的参数类型,或者作为函数的返回类型,还可以用作函数主体中的注释类型。在这些情况下,类型参数会在函数调用时被实际类型所替换。

3.你可提供多个类型参数,将它们都写在尖括号中,用逗号分开

扩展一个泛型类型:

1.当你扩展一个泛型类型的时候,你并不需要在扩展的定义中提供类型参数列表

2.原始类型定义中声明的类型参数列表在扩展中可以直接使用,并且这些来自原始类型中的参数名称会被用作原始定义中类型参数的引用。

类型约束:

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

func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) { // 这里是泛型函数的函数体部分 }

2.可以在参数列表中通过 where 子句为关联类型定义约束。一个 where 子句能够使一个关联类型符合某个特定的协议,以及某个特定的类型参数和关联类型必须类型相同。你可以通过将 where 关键字紧跟在类型参数列表后面来定义 where 子句,where 子句后跟一个或者多个针对关联类型的约束,以及一个或多个类型参数和关联类型间的相等关系。

定义一个协议时关联类型:

1.关联类型作为协议的一部分,为某个类型提供了一个占位名(或者说别名),其代表的实际类型在协议被采纳时才会被指定。

2.你可以通过 typealias 关键字来指定关联类型。

*/

//栈:后进先出

struct Stack<Element> {

var items = [Element]()

mutating func push(item: Element) {

items.append(item)

}

mutating func pop() -> Element {

return items.removeLast()

}

}

var stackOfStrings = Stack<String>()

stackOfStrings.push("uno")

stackOfStrings.push("dos")

stackOfStrings.push("tres")

stackOfStrings.push("cuatro") // 栈中现在有 4 个字符串

let fromTheTop = stackOfStrings.pop() // fromTheTop 的值为 "cuatro",现在栈中还有 3 个字符串

//扩展,直接使用占位类型

extension Stack {

var topItem: Element? {

return items.isEmpty ? nil : items[items.count - 1]

}

}

//====================

func findIndex<T: Equatable>(array: [T], _ valueToFind: T) -> Int? {

for (index, value) in array.enumerate() {

if value == valueToFind {       //不是所有的 Swift 类型都可以用等式符(==)进行比较,所以需要将T约束为符合Equatable协议,该协议要求任何符合该协议的类型必须实现等式符(==),从而能对符合该协议的类型的任意两个值进行比较

return index

}

}

return nil

}

//===================

protocol Container {

typealias ItemType  //类型关联

mutating func append(item: ItemType)

var count: Int { get }

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

}

struct IntStack: Container {

// IntStack 的原始实现部分

var items = [Int]()

mutating func push(item: Int) {

items.append(item)

}

mutating func pop() -> Int {

return items.removeLast()

}

// Container 协议的实现部分

typealias ItemType = Int    //将 Container 协议中抽象的 ItemType 类型转换为具体的 Int 类型。由于 Swift 的类型推断,你实际上不用在 IntStack 的定义中声明 ItemType 为 Int

mutating func append(item: Int) {

self.push(item)

}

var count: Int {

return items.count

}

subscript(i: Int) -> Int {

return items[i]

}

}

struct Stack1<Element>: Container {

// Stack<Element> 的原始实现部分

var items = [Element]()

mutating func push(item: Element) {

items.append(item)

}

mutating func pop() -> Element {

return items.removeLast()

}

// Container 协议的实现部分

mutating func append(item: Element) {

self.push(item)

}

var count: Int {

return items.count

}

subscript(i: Int) -> Element {

return items[i]

}

}

//=========================类型参数的约束

func allItemsMatch<C1: Container, C2: Container where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>

(someContainer: C1, _ anotherContainer: C2) -> Bool {

// 检查两个容器含有相同数量的元素

if someContainer.count != anotherContainer.count {

return false

}

// 检查每一对元素是否相等

for i in 0..<someContainer.count {

if someContainer[i] != anotherContainer[i] {

return false

}

}

// 所有元素都匹配,返回 true

return true

}

swift学习笔记之-泛型的更多相关文章

  1. 【swift学习笔记】二.页面转跳数据回传

    上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...

  2. Swift学习笔记(一)搭配环境以及代码运行成功

    原文:Swift学习笔记(一)搭配环境以及代码运行成功 1.Swift是啥? 百度去!度娘告诉你它是苹果最新推出的编程语言,比c,c++,objc要高效简单.能够开发ios,mac相关的app哦!是苹 ...

  3. swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  4. swift学习笔记4——扩展、协议

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  5. swift学习笔记3——类、结构体、枚举

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  6. swift学习笔记2——函数、闭包

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  7. swift学习笔记1——基础部分

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  8. Swift学习笔记一

    最近计划把Swift语言系统学习一下,然后将MagViewer用这种新语言重构一次,并且优化一下,这里记录一下Swift的学习笔记. Swift和Objective-C相比,在语法和书写形式上做了很多 ...

  9. 记录:swift学习笔记1-2

    swift还在不断的更新做细微的调整,都说早起的鸟儿有虫吃,那么我们早点出发吧,趁着国内绝大多数的coder们还没有开始大范围普遍应用. 网上有些大神说:swift很简单!我不同意这个观点,假如你用h ...

随机推荐

  1. SQLServer学习笔记系列4

    一.写在前面的话 好多天没有记录sql学习笔记了,要坚持下去,坚信每一点的进步都是为在积蓄力量.今天看到一幅图,特此分享出来. 通过这幅图,我看到的是每人站在自己的角度看问题,感受是不一样的,就如同学 ...

  2. [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3

    [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3 // */ // ]]>   [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3 Table of C ...

  3. Elasticsearch 管理文档

    ES支持近实时的索引.更新.查询.删除文档,近实时就意味着刚刚索引的数据需要1秒钟后才能搜索到,这也是与传统的SQL数据库不同的地方. 更多的ES文档资料参考:Elasticsearch官方文档翻译 ...

  4. ES6笔记(6)-- Set、Map结构和Iterator迭代器

    系列文章 -- ES6笔记系列 搞ES6的人也是够无聊,把JS弄得越来越像Java.C++,连Iterator迭代器.Set集合.Map结构都出来了,不知道说什么好... 一.简单使用 1. iter ...

  5. css异常

    1.0 样式的引用顺序不对会导致样式显示不正常.个人推荐:把别人写好的样式引用在最前面,自己写的放在后面. 2.0 UC手机浏览器 UC手机浏览器在识别到页面文字很多的情况下会自动放大字体优化阅读体验 ...

  6. 基于MVC4+EasyUI的Web开发框架经验总结(7)--实现省份、城市、行政区三者联动

    为了提高客户体验和进行一些技术探索,现在正准备把我自己的客户关系管理系统CRM在做一个Web的版本,因此对基于MVC的Web界面继续进行一些研究和优化,力求在功能和界面上保持和Winform一致,本文 ...

  7. easyui combobox 值怎样获取

    $('#com').combobox('getValue')获取当前选中的值$('#com').combobox('getText')获取当前选中的文字

  8. DIP依赖倒置原则

    一.定义 1.高层模块不应该依赖低层模块,二者都应该依赖抽象 2.抽象不应该依赖于细节.细节应该依赖于抽象 二.层次化 1.简单介绍 结构良好的面向对象架构都具有清晰的层次定义,每个层次通过一个定义良 ...

  9. .Net中的并行编程-1.路线图

    最近半年一直研究用.net进行并行程序的开发与设计,再研究的过程中颇有收获,所以画了一个图总结了一下并行编程的基础知识点,这些知识点是并行编程的基础,有助于我们编程高性能的程序,里面的某些结构实现机制 ...

  10. 第一讲:WCF介绍

    代码 https://yunpan.cn/cPns5DkGnRGNs   密码:3913                                                         ...