内容简介:里面只有一个方法next( )方法是用下面我们用迭代器写一个斐波那契数列(0,1,1,2,3,5,8,13.....)。
里面只有一个方法 next( )
public protocol IteratorProtocol { ///关联类型 Element 指定了迭代器产生的值的类型 ///如 subViews的迭代原生类型就是View 可以不用写,编译器根据next()的返回值自动判断。 associatedtype Element ///你只需要在每次调用的时候返回下一个值,结束时返回nil public mutating func next() -> Self.Element? } 复制代码
next( )方法是用 mutating
关键字修饰。 几乎所有的迭代器都要求是 可变状态
,这样才可以管理在序列中的当前位置----(这句话的意思到现在还没太理解。大家可以把自己的理解写上了,thanks~)
下面我们用迭代器写一个斐波那契数列(0,1,1,2,3,5,8,13.....)。
struct FibsNumIterator:IteratorProtocol { var startNum = (0, 1) mutating func next() -> Int? { let nextNum = startNum.0 startNum = (startNum.1, startNum.0 + startNum.1) return nextNum } } 复制代码
这个迭代器不返回nil, 就会产生无穷的数组。 程序会因为类型溢出而crash。
注:迭代器是 单向结构
,只能按照增加的方向前进,不能倒退或者重置。
准守序列(sequence)协议
下面我们通过一个打印一个字符串所有前缀的demo 通过 自定义迭代器
和 自定义集合
去写一个属于你的集合~
第一步: 创建一个 迭代器
(Iterator)
struct PrefixStrIterator:IteratorProtocol { var string: String var offset: String.Index init(string:String) { self.string = string offset = string.startIndex } ///写协议方法 mutating func next() -> String? { guard offset < string.endIndex else { return nil} offset = string.index(after: offset) return String(string[string.startIndex..<offset]) } } 复制代码
第二步: 创建一个使用这个迭代器的 序列
(sequence)
///step2.创建一个属于你的集合 struct PrefixSequence: Sequence { var string: String ///协议方法:返回一个迭代器 func makeIterator() -> PrefixStrIterator { return PrefixStrIterator(string: string) } } 复制代码
第三步: run~
///myfirstSquence 我的第一个集合 for prefixStr in PrefixSequence(string: "Hi~LiaoWorking!") { print(prefixStr) // H // Hi // Hi~ // Hi~L // Hi~Li // Hi~Lia // Hi~Liao // Hi~LiaoW // Hi~LiaoWo // Hi~LiaoWor // Hi~LiaoWork // Hi~LiaoWorki // Hi~LiaoWorkin // Hi~LiaoWorking // Hi~LiaoWorking! } 复制代码
迭代器和值语义
先说说值语义和引用语义,这两个定义无论在今后的学习还是日常开发细节中会经常遇到~ 敲黑板!
作用对象 | 特性 | |
---|---|---|
值语义 | struct,应该还有其他类型。待补充。 | 赋值时不存在引用,复制了一份过去了 |
引用语义 | class | 赋值时存在引用 |
注:但 AnyIterator
这个是引用对象。。(协议章中的类型抹消的内容我们再具体说~)
基于函数的迭代器和序列
继续写一个Demo: AnyIterator
还有一个初始化方法就是直接接受next()函数来当做参数。然后通过引用语义的特性,我们可以不创建新的类型就写一个斐波那契迭代器
/// 通过引用语义的特性写斐波那契 func fibsIterator() -> AnyIterator<Any> { var startNum = (0, 1) return AnyIterator{ let nextNum = startNum.0 startNum = (startNum.1 , startNum.0 + startNum.1) return nextNum } } 复制代码
这个是高阶知识点,的确没有第二章的生动。了解一下也挺好啊~~
无限序列
序列可以是 无限
的,而集合是 有限
的。
不稳定序列
Sequence文档明确指出序列并不保证能被多次遍历。 原因是Sequence协议并不关心里面的序列元素会不会销毁。
知识点1:这就是为什么在集合类型中.first 在序列中并不存在。
序列sequence和迭代器Iterator的关系
迭代器Iterator可以看成即将返回的元素组成的 不稳定
序列sequence
子序列
Sequence还有一个关联类型 SubSequence
在返回原序列Sequence的 切片slice操作
中,SubSequence会被当做返回值的子类。
SubSequence 有一些常用方法
prefix suffix dropFirst dropLast split 复制代码
在项目中其实经常会遇到SubSequence,如string的SubSequence等等。。(哈哈才一个,这个不能叫“经常”。其实是会经常遇到SubSequence。不过一时之间想不起来了:sweat_smile:)
以上所述就是小编给大家介绍的《[swift 进阶]读书笔记-集合类型协议 C3P1_序列》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Scala 中的集合(二):集合性能比较
- Scala 中的集合(二):集合性能比较
- 《面试知识,工作可待:集合篇》:Java 集合面试知识大全
- 如何对集合对象求合计,然后追加在该集合对象中
- MongoDB指南---14、特殊的索引和集合:固定集合、TTL索引、全文本索引
- Python 集合相关操作
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
在线进制转换器
各进制数互转换器
HSV CMYK 转换工具
HSV CMYK互换工具