Sequence
Sequence是一系列相同類型的值的集合,并且提供對這些值得迭代能力
迭代一個(gè)Sequence最常見的方式就是for-in瞎嬉,并且提供對這些值得迭代能力
for element in someSequence {
doSomething(with: element)
}
我們經(jīng)常把for-in循環(huán)用到Array钝满,Dictonary,set等數(shù)據(jù)結(jié)構(gòu)中,那是因?yàn)樗鼈兌际菍?shí)現(xiàn)了Sequence協(xié)議赠橙。
Sequence協(xié)議的定義:
protocol Sequence{
associatedtype Iterator:IteratorProtocol
func makeIterator()->Iterator
}
Sequence的協(xié)議里只有一個(gè)必須實(shí)現(xiàn)的方法就是makeIterator(),
makeIterator()需要返回一個(gè)Iterator愤炸,他就是一個(gè)IteratorProtocol類型期揪。
只要提供一個(gè)Iterator就能實(shí)現(xiàn)Sequence,那么Iterator又是什么了规个?凤薛??
Iterator
Iterator 在 Swift 3.1 標(biāo)準(zhǔn)庫中即為 IteratorProtocol诞仓,它用來為 Sequence 提供迭代能力缤苫。對于 Sequence,我們可以用for-in來迭代其中的元素墅拭,其實(shí)for-in的背后是 IteratorProtocol 在起作用活玲。
IteratorProtocol 的定義如下:
public protocol IteratorProtocol{
associatedtype Element
public mutating func next()->Self.Element?
}
associatedtype 聲明了元素的類型
next()用來返回Sequence中的下一個(gè)元素,或者當(dāng)沒有了下一個(gè)元素就返回nil
Iterator實(shí)現(xiàn)舉例說明
舉例1
struct SimplestIterator:IteratorProtocol {
typealias Element = Int
mutating func next() -> Int? {
return nil
}
}
這個(gè)例子中的Iterator不會(huì)迭代出任何元素,確切的說翼虫,這個(gè)Iterator在迭代時(shí)僅調(diào)用一次next()就結(jié)束了屑柔。
舉例2
struct ConstantIterator:IteratorProtocol {
typealias Element = Int
mutating func next() -> Int? {
return 1
}
}
這個(gè)一直迭代出的是1
實(shí)現(xiàn)一個(gè)Sequence
實(shí)現(xiàn)一個(gè)Sequence首先要實(shí)現(xiàn)一個(gè)Iterator
實(shí)現(xiàn)一個(gè)Iterator,接收一個(gè)字符串?dāng)?shù)組珍剑,并可以迭代這個(gè)數(shù)組中的所有字符串的首字母掸宛,當(dāng)數(shù)組中的最后一個(gè)字符串迭代完后迭代完成,退出迭代
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))
}
}
這個(gè)Iterator的需要輸入一個(gè)字符串?dāng)?shù)組招拙,在哪next()中唧瘾,判斷邊界,并返回?cái)?shù)組為offset的字符串的首字母别凤,并將offset加1
有了實(shí)現(xiàn)好的Iterator饰序,就可以簡單的用他實(shí)現(xiàn)Sequence,在makeIterator()中返回這個(gè)Iterator即可
struct FirstLetterSequence:Sequence {
let strngs:[String]
func makeIterator() -> FirstLetterIterator {
return FirstLetterIterator(strings:strngs)
}
}
現(xiàn)在Sequence已經(jīng)實(shí)現(xiàn)完成了规哪,
for letter in FirstLetterSequence(strngs:["apple","banana","orange"]) {
print(letter)
}
打印結(jié)果:
a
b
o
值類型 Iterator 和引用類型 Iterator
值類型 Iterator
一般 Iterator 都是值類型的求豫,值類型的 Iterator 的意思是:當(dāng)把 Iterator 賦值給一個(gè)新變量時(shí),是把原 Iterator 的所有狀態(tài)拷貝了一份賦值給新的 Iterator诉稍,原 Iterator 在繼續(xù)迭代時(shí)不會(huì)影響新的 Iterator蝠嘉。
例如用stride函數(shù)創(chuàng)建一個(gè)簡單的 Sequence,它從 0 開始杯巨,到 9 截止蚤告,每次遞增 1,即為 [0, 1, 2, ..., 8, 9]服爷。
然后獲取到它的 Iterator杜恰,調(diào)用 next() 進(jìn)行迭代。
let seq = stride(from: 0, to: 10, by: 1)
var i1 = seq.makeIterator()
print(i1.next())
print(i1.next())
輸出結(jié)果
Optional(0)
Optional(1)
然后做一個(gè)賦值操作仍源,建一個(gè)新的i2
var i2= i1
然后輸出
print(i1.next())
print(i1.next())
print(i2.next())
print(i2.next())
輸出結(jié)果
Optional(0)
Optional(1)
Optional(0)
Optional(1)
這里的i1和i2相互不影響心褐,賦值對i1做了一份完整的拷貝,這里的Iterator是一個(gè)值類型的Iterator
應(yīng)用類型的Iterator
可以把任何一個(gè)值類型 Iterator 用AnyIterator這個(gè)包一下就形成了一個(gè)引用類型的 Iterator镜会。
var i3 = AnyIterator(i1)
var i4 = i3
輸出
print(i3.next())
print(i4.next())
print(i3.next())
print(i4.next())
輸出結(jié)果
Optional(0)
Optional(1)
Optional(2)
Optional(3)
引用類型的 Iterator檬寂,再賦值給一個(gè)新的變量后终抽,新的 Iterator 和原 Iterator 在進(jìn)行迭代時(shí)會(huì)互相對對方產(chǎn)生影響戳表。
學(xué)習(xí)博客參考