2016-12-29 83 views
1

我想了解如何實現符合LazySequenceProtocol的擴展。LazySequenceProtocol示例不起作用

所以我也跟着從Apple's API reference的示例代碼如下:

struct LazyScanIterator<Base : IteratorProtocol, ResultElement> 
: IteratorProtocol { 
    mutating func next() -> ResultElement? { 
     return nextElement.map { result in 
      nextElement = base.next().map { nextPartialResult(result, $0) } 
      return result 
     } 
    } 
    private var nextElement: ResultElement? // The next result of next(). 
    private var base: Base     // The underlying iterator. 
    private let nextPartialResult: (ResultElement, Base.Element) -> ResultElement 
} 

struct LazyScanSequence<Base: Sequence, ResultElement> 
    : LazySequenceProtocol // Chained operations on self are lazy, too 
{ 
    func makeIterator() -> LazyScanIterator<Base.Iterator, ResultElement> { 
     return LazyScanIterator(nextElement: initial, base: base.makeIterator(), nextPartialResult) 
    } 

    private let base: Base 
    private let initial: ResultElement 
    private let nextPartialResult: (ResultElement, Base.Iterator.Element) -> ResultElement 
} 

extension LazySequenceProtocol { 
    func scan<ResultElement>(
     _ initial: ResultElement, 
     _ nextPartialResult: (ResultElement, Iterator.Element) -> ResultElement 
     ) -> LazyScanSequence<Self, ResultElement> { 
     return LazyScanSequence(
      initial: initial, base: self, nextPartialResult) 
    } 
} 

,但說的XCode,

無法將類型的價值 'ResultElement' 預期參數類型 '?_'

上線return LazyScanIterator(nextElement: initial, base: base.makeIterator(), nextPartialResult)

我想使錯誤消失,但沒有工作,所以我只是刪除所有代碼從mutating func next()部分在LazyScanIterator結構和剛剛返回​​與ResultElement代替ResultElement?改變nextElement類型。

好吧,錯誤消失了,但現在我有一個新的在同一行。

無法將類型的價值 '(ResultElement,Base.Iterator.Element) - > ResultElement' 預期參數類型 '(_,_) - > _'

有什麼不對本示例代碼?

回答

1

我想問題是構造函數不存在。

這工作得很好,我的遊樂場(寫在斯威夫特3)

import Foundation 

struct LazyScanIterator<Base : IteratorProtocol, ResultElement> 
: IteratorProtocol { 
    private var nextElement: ResultElement? // The next result of next(). 
    private var base: Base     // The underlying iterator. 
    private let nextPartialResult: (ResultElement, Base.Element) -> ResultElement 

    mutating func next() -> ResultElement? { 
     return nextElement.map { result in 
      nextElement = base.next().map { nextPartialResult(result, $0) } 
      return result 
     } 
    } 

    init(nextElement: ResultElement, base: Base, nextPartialResult: @escaping (ResultElement, Base.Element) -> ResultElement) { 
     self.nextElement = nextElement 
     self.base = base 
     self.nextPartialResult = nextPartialResult 
    } 
} 

struct LazyScanSequence<Base: Sequence, ResultElement> 
    : LazySequenceProtocol // Chained operations on self are lazy, too 
{ 
    private let base: Base 
    private let initial: ResultElement 
    private let nextPartialResult: (ResultElement, Base.Iterator.Element) -> ResultElement 

    func makeIterator() -> LazyScanIterator<Base.Iterator, ResultElement> { 
     return LazyScanIterator(nextElement: initial, base: base.makeIterator(), nextPartialResult: nextPartialResult) 
    } 

    init(initial: ResultElement, base: Base, nextPartialResult: @escaping (ResultElement, Base.Iterator.Element) -> ResultElement) { 
     self.initial = initial 
     self.base = base 
     self.nextPartialResult = nextPartialResult 
    } 
} 

extension LazySequenceProtocol { 
    func scan<ResultElement>(
     _ initial: ResultElement, 
     _ nextPartialResult: @escaping (ResultElement, Iterator.Element) -> ResultElement 
     ) -> LazyScanSequence<Self, ResultElement> { 
     return LazyScanSequence(
      initial: initial, base: self, nextPartialResult: nextPartialResult) 
    } 
} 

Array((1..<6).lazy.scan(0, +)) // will result : [0, 1, 3, 6, 10, 15]