2. Swift IteratorProtocol

IteratorProtocol協(xié)議和Sequence的聯(lián)系是非常緊密的。序列通過創(chuàng)建一個迭代器來訪問它們的元素,迭代器跟蹤它的迭代過程并在它通過序列前進時每次返回一個元素。

當你在array, set, 或者其他集合和序列使用for - in的時候就會用到這個類型的迭代器冬殃。swift使用隊列或者集合的內(nèi)部迭代器以便使用for - in這種語言結(jié)構(gòu)。

直接使用迭代器遍歷元素和用for - in遍歷同一個數(shù)組是等價的叁怪。比如你使用for - in遍歷數(shù)組["Antelope", "Butterfly", "Camel", "Dolphin"]

     let animals = ["Antelope", "Butterfly", "Camel", "Dolphin"]
     for animal in animals {
        print(animal)
     }
     // Prints "Antelope"
     // Prints "Butterfly"
     // Prints "Camel"
     // Prints "Dolphin"

但是在他的底層使用的是Array的迭代器遍歷這個數(shù)組

     var animalIterator = animals.makeIterator()
     while let animal = animalIterator.next() {
         print(animal)
     }
     // Prints "Antelope"
     // Prints "Butterfly"
     // Prints "Camel"
     // Prints "Dolphin"

animals.makeIterator()返回當前數(shù)組的迭代器审葬,下一步當while循環(huán)調(diào)用了迭代器的next()方法時,元素就被一個一個取出來了奕谭,直到next()返回nil的時候退出涣觉。

直接使用迭代器


  • 在通常的情況下我們直接使用for-in就可以滿足,但是在某些場合下我們會直接使用迭代器血柳。
  • 一個例子就是reduce1(_:)函數(shù)官册,類似于標準庫中定義的reduce(_:_:)函數(shù)(帶有一個初始值和一個結(jié)合閉包),reduce1(_:)需要用到序列的第一個元素作為初始值难捌。
  • 下面就是reduce1(_:)的一個實現(xiàn)膝宁,直接使用迭代器來取初始值
extension Sequence {
         func reduce1(_ nextPartialResult: (Iterator.Element, Iterator.Element) -> Iterator.Element) -> Iterator.Element? {
             var i = makeIterator()
             guard var accumulated = i.next() else {
                return nil
             }
             while let element = i.next() {
                 accumulated = nextPartialResult(accumulated, element)
             }
             return accumulated
         }
     }

reduce1(_:)方法對于某些隊列的操作更加簡單,這里我們找出animals數(shù)組中最長的字符串:

    let longestAnimal = animals.reduce1 { current, element in
         if current.characters.count > element.characters.count {
             return current
         } else {
             return element
         }
     }
     // print(longestAnimal)
     // Prints "Butterfly"

使用多個迭代器


每當你在一個隊列使用多個迭代器(或者for-in)時根吁, 請確保特殊的隊列能支持重復(fù)迭代员淫,或者確保你知道他的具體類型,或者確保它遵守Collection協(xié)議击敌。

從各自獨立的迭代器到調(diào)用各自獨立的迭代器的序列的makeIterator()方法介返,而不是通過復(fù)制。復(fù)制迭代器是安全的,但是調(diào)用復(fù)制后的迭代器的next()方法圣蝎,就有可能會使其他這個迭代器的副本失效刃宵。for-in循環(huán)則是安全的
....

在自定義類型中合適的添加IteratorProtocol協(xié)議


實現(xiàn)一個合適迭代器很簡單,定義一個next()函數(shù)徘公,當前進一步的時候返回當前的元素组去,當這個序列結(jié)束,next()函數(shù)返回nil步淹。
例如,假設(shè)我們有個Countdown序列诚撵,你可以用一個起始數(shù)字初始化這個序列缭裆,然后迭代到0。這個數(shù)據(jù)結(jié)構(gòu)定義的很短:它僅僅只有起始數(shù)和Sequence需要的makeIterator()方法寿烟。

struct Countdown: Sequence {
    let start: Int
    func makeIterator() -> CountdownIterator {
        return CountdownIterator(self)
    }
}

makeIterator()返回一個自定義迭代器CountdownIterator澈驼。CountdownIterator追蹤Countdown序列的迭代和它返回值的次數(shù)

struct CountdownIterator: IteratorProtocol {
    let countdown: Countdown
    var times = 0
    
    init(_ countdown: Countdown) {
        self.countdown = countdown
    }
    
    mutating func next() -> Int? {
        let nextNumber = countdown.start - times
        guard nextNumber > 0
            else { return nil }
        
        times += 1
        return nextNumber
    }
}

每次next()方法是被當前CountdownIterator調(diào)用,他計算下一個新的數(shù)組筛武,檢查多久會減少到0缝其,然后返回數(shù)字,或者在迭代器返回完序列的元素之后返回nil
調(diào)用:

 let threeTwoOne = Countdown(start: 3)
 for count in threeTwoOne {
    print("\(count)...")
}
// Prints "3..."
// Prints "2..."
// Prints "1..."

...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末徘六,一起剝皮案震驚了整個濱河市内边,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌待锈,老刑警劉巖漠其,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異竿音,居然都是意外死亡和屎,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門春瞬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柴信,“玉大人,你說我怎么就攤上這事宽气∷娉#” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵抹竹,是天一觀的道長线罕。 經(jīng)常有香客問我,道長窃判,這世上最難降的妖魔是什么钞楼? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮袄琳,結(jié)果婚禮上询件,老公的妹妹穿的比我還像新娘燃乍。我一直安慰自己,他們只是感情好宛琅,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布刻蟹。 她就那樣靜靜地躺著,像睡著了一般嘿辟。 火紅的嫁衣襯著肌膚如雪舆瘪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天红伦,我揣著相機與錄音英古,去河邊找鬼。 笑死昙读,一個胖子當著我的面吹牛召调,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛮浑,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼唠叛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了沮稚?” 一聲冷哼從身側(cè)響起艺沼,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蕴掏,沒想到半個月后澳厢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡囚似,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年剩拢,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饶唤。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡徐伐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出募狂,到底是詐尸還是另有隱情办素,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布祸穷,位于F島的核電站性穿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏雷滚。R本人自食惡果不足惜需曾,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧呆万,春花似錦商源、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至出爹,卻和暖如春庄吼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背严就。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工霸褒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像差油,于是被迫代替她去往敵國和親估脆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理衰倦,服務(wù)發(fā)現(xiàn)袒炉,斷路器,智...
    卡卡羅2017閱讀 134,652評論 18 139
  • 一樊零、基礎(chǔ)知識:1我磁、JVM、JRE和JDK的區(qū)別:JVM(Java Virtual Machine):java虛擬機...
    殺小賊閱讀 2,378評論 0 4
  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,788評論 0 38
  • 我認真地行走在 絕望的邊緣上 你卻站在原點 冷眼旁觀著我的流離 有時停留在你的肩膀上 可是永遠都不能依靠 所以 我...
    柒憶閱讀 298評論 2 4
  • 1驻襟、我媽和我爸是地地道道的農(nóng)民夺艰,讀過幾年書,認識字而已沉衣。因為讀書少郁副,所以省吃儉用把我和妹妹供上大學(xué)。作為村里的第一...
    明媚朵朵閱讀 352評論 2 0