含义:
一种可以对其元素进行连续,迭代访问的类型。
for - in 循环
// MARK:- For in 遍历
extension SequenceController {
/*
for in
可以对任何序列 “Sequence” 执行大量操作。
例如:
检查序列是否包含特定值,您可以一次测试每个值,知道找到匹配或到达序列的末尾。
*/
// 常用的方法,可以对任何序列执行大量操作。
func forInALoop() {
let oneTwoThree = 1...3
for number in oneTwoThree {
print(number)
}
}
// 这个例子是:检查一个特定的昆虫是否在数组中
func forInALoopTwo() {
let bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"]
var hasMosquito = false
for bug in bugs {
if bug == "Mosquito" {
hasMosquito = true
break
}
}
print("'bugs' has a mosquito: \(hasMosquito)")
}
}
sequence循环
// MARK:- sequence 循环
extension SequenceController{
// 精简 for - in
func sequenceALoop() {
let bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"]
if bugs.contains("Mosquito") {
print("Break out the bug spray.")
} else {
print("Whew, no mosquitos!")
}
}
}
重复访问
/* sequence 协议
1. 为许多常见的操作提供了依赖于对序列值得顺序访问的默认实现。
2. 为了更清晰,更简洁的代码。这个实例使用的是 contains(_:)方法
3. 每个序列都继承自 Sequence ,而不是手动迭代
4. sequence 协议对 符合类型是否会被破坏被迭代无要求。
因此,不要假设一个for - in 序列上的多个循环会恢复迭代 或从头开始。
*/
for element in sequence {
if ... some condition { break }
}
for element in sequence {
// No defined behavior
}
在 这种情况下,不能假设序列是可消耗的,并且将恢复迭代。
或者序列是集合,并将从第一个元素重新启动迭代。
自定义类型
如要像自己的自定义类型添加Sequence,需要添加返回迭代器的方法 -> makeIterator()
或者,如果您的类型可以充当自己的迭代器,实现协议的需求并声明两者的一致性,就足够了。 -> IteratorProtocolSequenceIteratorProtocol
// 这是 Countdown 自己做为迭代器的序列的定义,此方法提供默认实现
struct Countdown: Sequence, IteratorProtocol {
var count: Int
mutating func next() -> Int? {
if count == 0 {
return nil
} else {
defer { count -= 1 }
return count
}
}
}
let threeToGo = Countdown(count: 3)
for i in threeToGo {
print(i)
}
// Prints "3"
// Prints "2"
// Prints "1"
预期表现
序列应该在O(1)中提供它的迭代器。该Sequence协议对元素访问没有其他要求,因此除非另有说明,否则遍历序列的例程应被视为O(n)。