2016-12-29 14 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)

私はエラーが離れて行くにしたかったが、何も働いていないので、私はちょうどLazyScanIterator構造体にmutating func next()部分からすべてのコードを削除し、ちょうど​​を返し、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] 
に適しています
関連する問題