Sequence

Sequence是一系列相同类型的值的集合,并且提供对这些值得迭代能力

迭代一个Sequence最常见的方式就是for-in,并且提供对这些值得迭代能力

for element in someSequence {

doSomething(with: element)

}

我们经常把for-in循环用到Array,Dictonary,set等数据结构中,那是因为它们都是实现了Sequence协议。

Sequence协议的定义:

protocol Sequence{

associatedtype Iterator:IteratorProtocol

func makeIterator()->Iterator

}

Sequence的协议里只有一个必须实现的方法就是makeIterator(),

makeIterator()需要返回一个Iterator,他就是一个IteratorProtocol类型。

只要提供一个Iterator就能实现Sequence,那么Iterator又是什么了???

Iterator

Iterator 在 Swift 3.1 标准库中即为 IteratorProtocol,它用来为 Sequence 提供迭代能力。对于 Sequence,我们可以用for-in来迭代其中的元素,其实for-in的背后是 IteratorProtocol 在起作用。

IteratorProtocol 的定义如下:

public protocol IteratorProtocol{

associatedtype Element

public mutating func next()->Self.Element?

}

associatedtype 声明了元素的类型

next()用来返回Sequence中的下一个元素,或者当没有了下一个元素就返回nil

Iterator实现举例说明

举例1

struct SimplestIterator:IteratorProtocol {

typealias Element = Int

mutating func next() -> Int? {

return nil

}

}

这个例子中的Iterator不会迭代出任何元素,确切的说,这个Iterator在迭代时仅调用一次next()就结束了。

举例2

struct ConstantIterator:IteratorProtocol {

typealias Element = Int

mutating func next() -> Int? {

return 1

}

}

这个一直迭代出的是1

实现一个Sequence

实现一个Sequence首先要实现一个Iterator

实现一个Iterator,接收一个字符串数组,并可以迭代这个数组中的所有字符串的首字母,当数组中的最后一个字符串迭代完后迭代完成,退出迭代

struct FirstLetterIterator:IteratorProtocol {

typealias Element = String

let stringArr:[String]

var offset:Int

init(strings:[String]) {

stringArr = strings

offset = 0

}

mutating func next() -> String? {

guard offset < stringArr.endIndex else {

return nil

}

let string = stringArr[offset]

offset += 1

return string.substring(to: string.index(string.startIndex, offsetBy: 1))

}

}

这个Iterator的需要输入一个字符串数组,在哪next()中,判断边界,并返回数组为offset的字符串的首字母,并将offset加1

有了实现好的Iterator,就可以简单的用他实现Sequence,在makeIterator()中返回这个Iterator即可

struct FirstLetterSequence:Sequence {

let strngs:[String]

func makeIterator() -> FirstLetterIterator {

return FirstLetterIterator(strings:strngs)

}

}

现在Sequence已经实现完成了,

for letter in FirstLetterSequence(strngs:["apple","banana","orange"]) {

print(letter)

}

打印结果:

a

b

o

值类型 Iterator 和引用类型 Iterator

值类型 Iterator

一般 Iterator 都是值类型的,值类型的 Iterator 的意思是:当把 Iterator 赋值给一个新变量时,是把原 Iterator 的所有状态拷贝了一份赋值给新的 Iterator,原 Iterator 在继续迭代时不会影响新的 Iterator。

例如用stride函数创建一个简单的 Sequence,它从 0 开始,到 9 截止,每次递增 1,即为 [0, 1, 2, ..., 8, 9]。

然后获取到它的 Iterator,调用 next() 进行迭代。

let seq = stride(from: 0, to: 10, by: 1)

var i1 = seq.makeIterator()

print(i1.next())

print(i1.next())

输出结果

Optional(0)

Optional(1)

然后做一个赋值操作,建一个新的i2

var i2= i1

然后输出

print(i1.next())

print(i1.next())

print(i2.next())

print(i2.next())

输出结果

Optional(0)

Optional(1)

Optional(0)

Optional(1)

这里的i1和i2相互不影响,赋值对i1做了一份完整的拷贝,这里的Iterator是一个值类型的Iterator

应用类型的Iterator

可以把任何一个值类型 Iterator 用AnyIterator这个包一下就形成了一个引用类型的 Iterator。

var i3 = AnyIterator(i1)

var i4 = i3

输出

print(i3.next())

print(i4.next())

print(i3.next())

print(i4.next())

输出结果

Optional(0)

Optional(1)

Optional(2)

Optional(3)

引用类型的 Iterator,再赋值给一个新的变量后,新的 Iterator 和原 Iterator 在进行迭代时会互相对对方产生影响。

学习博客参考

Swift 中的 Sequence(一)

Swift 中的 Sequence(二)

Swift中的Sequence基本的使用相关推荐

  1. swift java混合,如何在Swift中连接或合并数组?

    使用Swift 3,根据您的需求和品味,您可以选择其中一个 five following ways 来连接/合并两个数组 . 1.使用Swift标准库(: :)泛型运算符将两个数组合并为一个新数组 S ...

  2. Swift 中的 @autoclosure

    由于种种原因,掘金等第三方平台博客不再保证能够同步更新,欢迎移步 GitHub:github.com/kingcos/Per-.谢谢! Date Notes Swift Xcode Source Co ...

  3. 谈谈 Swift 中的 map 和 flatMap

    map 和 flatMap 是 Swift 中两个常用的函数,它们体现了 Swift 中很多的特性.对于简单的使用来说,它们的接口并不复杂,但它们内部的机制还是非常值得研究的,能够帮助我们够好的理解 ...

  4. Swift中的选项集合

    Swift3中的选项集合(Option Set) 作者:Ole Begemann,原文链接,原文日期:2016/09/28 译者:Lanford3_3:校对:saitjr:定稿:CMB 选项集合在OC ...

  5. 解决Swift中present(uiImagePickerController,animated: true,completion: nil)闪退的问题

    swift中开发选择图片上传,会使用到Tap Gesture Recognizer控件,对应 UITapGestureRecognizer API,以下是代码示例(取自IOS developer li ...

  6. Swift 中使用 SQLite——批量更新(事务处理)

    本文是Swift 中使用 SQLite系列的收官之作,介绍一下在数据库中的批量更新. 事务 在准备做大规模数据操作前,首先开启一个事务,保存操作前的数据库的状态 开始数据操作 如果数据操作成功,提交事 ...

  7. Swift 中使用 SQLite——打开数据库

    关于Swift中使用SQLite,接下来可能会分别从打开.增.删.改.查,几个方面来介绍SQLite的具体使用,这一篇重点介绍一下如何打开. 定义全局数据库访问句柄 /// 全局数据库访问句柄 pri ...

  8. 探索 Swift 中的 MVC-N 模式

    作者:Marcus Zarra(twitter:@mzarra) Marcus 将会为大家介绍一种设计模式,他曾经在那些需要从互联网进行大量频繁数据请求的 iOS 应用当中使用此设计模式.这个设计采用 ...

  9. Swift 中的内存管理详解

    这篇文章是在阅读<The Swift Programming Language>Automatic Reference Counting(ARC,自动引用计数)一章时做的一些笔记,同时参考 ...

最新文章

  1. 最长不下降子序列(推广问题)
  2. Java 程序员必备的 15 个框架,前 3 个地位无可动摇!
  3. 猴子请来的逗比项目流水总结
  4. 理解Docker(5):Docker 网络
  5. iOS进阶_Socket(Socket简介代码演练)
  6. python中find函数忽略大小写_python字符串(大小写、判断、查找、分割、拼接、裁剪、替换、格式化)...
  7. Java基础篇:四种代码块详解
  8. eDMA结构及工作机理的简单介绍
  9. 【转】教你何时开启水果机上的HDR拍照
  10. l2tp pptp相关的一些记录
  11. Win10安装和配置IIS web服务器环境来运行ASP(动态服务器页面)脚本
  12. pytdx 获取板块指数_通达信板块代码,怎么查看各行业板块指数?
  13. amd编码器 hevc_HEVC/H.265硬件编码器实现杂谈
  14. 数字化转型,金融行业的下一个引爆点
  15. 理想边界尺寸怎么算_GDamp;T 几何尺寸和公差 | ASME14.52018标准弄错了吗?
  16. python 入门篇 之 正则表达式re.findall的使用
  17. nas linux手机照片备份,本身着手,组建简洁好用的NAS!(存储同步篇)
  18. 测试驱动需求分析--需求文档评审实例
  19. 实验室-关于老铁整一个社会语录api与网抑云热评api(并引入百度语音tts)
  20. 爬取新浪微博某超话用户信息,进行EDA分析

热门文章

  1. SQL Server - SQL Server 2016新特性之 --- Query Store
  2. MVC Razor视图引擎控件
  3. IronRuby 发布第一个版本
  4. windows--bat--删除当前脚本del %0
  5. cocos2dx 实现简单的文件上传到php服务器的demo
  6. 大数据之-Hadoop3.x_MapReduce_FileInputFormat切片机制---大数据之hadoop3.x工作笔记0106
  7. AndroidStudio安卓原生开发_UI高级_RecyclerView_循环复用控件_代替ListView_GridView---Android原生开发工作笔记121
  8. ES6新特性_Promise介绍与基本使用---JavaScript_ECMAScript_ES6-ES11新特性工作笔记024
  9. STM32工作笔记0039---认识电路图中的DS203,MS,L等
  10. SpringCloud工作笔记075---SpotBugs介绍--优化java代码的质量