内容简介:里面只有一个方法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 集合相关操作
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First Rails
David Griffiths / O'Reilly Media / 2008-12-30 / USD 49.99
Figure its about time that you hop on the Ruby on Rails bandwagon? You've heard that it'll increase your productivity exponentially, and allow you to created full fledged web applications with minimal......一起来看看 《Head First Rails》 这本书的介绍吧!