//泛型(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. backbone库学习-model

    backbone库的结构: http://www.cnblogs.com/nuysoft/archive/2012/03/19/2404274.html 本文所有例子来自于http://blog.cs ...

  2. [New Portal]Windows Azure Virtual Machine (17) Virtual Machine成本分析

    <Windows Azure Platform 系列文章目录> 在Windows Azure VM里,计费模式是和以下几个因素有关: 成本1: VM Type and VM Size 具体 ...

  3. JAVA 设计模式 模板方法模式

    定义 模板方法模式 (Template Method) 定义了一个操作中的算法的骨架,而将部分步骤的实现在子类中完成. 模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 模 ...

  4. 使用elk+redis搭建nginx日志分析平台

    elk+redis 搭建nginx日志分析平台 logstash,elasticsearch,kibana 怎么进行nginx的日志分析呢?首先,架构方面,nginx是有日志文件的,它的每个请求的状态 ...

  5. 解析导航栏的url--selnium,beautifulsoup实战

    前段时间做ui自动化测试的时候,导航栏菜单始终有点问题,最后只好直接获取到url,然后直接使用driver.get(url)进入页面: 包括做压测的时候,比如我要找出所有报表菜单的url,这样不可能手 ...

  6. Redis使用总结(1):基础使用

    Redis的安装及启动 安装 Ubuntu sudo apt-get install redis Mac sudo brew install redis Windows 不支持 启动 首先启动Redi ...

  7. 【转载】那些年我们一起清除过的浮动demo

    返回文章:那些年我们一起清除过的浮动 闭合浮动 与 清除浮动 的区别 .main:很抱歉,现代浏览器中我没能把warp撑高(float:left) .side:我也浮动了(float:left) .f ...

  8. 在Windows Phone 8中使用Live Connect并保持登陆状态

    Live Connect可以让各种客户端访问Live账号.获取好友列表.访问One Drive的文件等,官方地址在此:http://msdn.microsoft.com/zh-cn/live/ff51 ...

  9. cdnjquery加载失败加载本地

    <script type="text/javascript" src="//libs.baidu.com/jquery/1.7.2/jquery.min.js&qu ...

  10. 水晶报表13.x(Crystal Reports for VS2010)的安装部署经验

    这两天搞安装包真心坎坷,一个问题接一个问题,先是为了实现自定义动作现啃vbs,后面又是安装过程老是报错: 各种搜索.各种尝试,总算搞掂,积累了些经验,分享一下. 首先CR for VS2010的所有东 ...