我正在尝试了解如何实现符合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
部分的所有代码,只返回base.next()
并更改了nextElement
的类型{1}} ResultElement
代替ResultElement?
。
嗯,错误消失但现在我在同一行有一个新的。
无法转换类型的值'(ResultElement,Base.Iterator.Element) - &gt; ResultElement'到期望的参数类型'(_,_) - &gt; _'
此示例代码有什么问题?
答案 0 :(得分:1)
我猜问题是构造函数不存在。
这在我的操场上很好用(用Swift 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]