将多个调用链接到同一方法时出现编译器问题
Compiler issues when chaining multiple calls to the same method
我正在尝试通过为所有惰性序列和集合重载 prefix(_ maxLength)
来修复 this bug,但我 运行 遇到了奇怪的编译器问题。
我正在使用 Xcode 9.0 beta 6 (9M214v),但它也可以在 4.0 的所有最新快照中重现。
给定以下迭代器,...
public struct LazyPrefixIterator <Base: IteratorProtocol>: IteratorProtocol {
public typealias Element = Base.Element
private var baseIterator: Base
private let maxLength: Int
private var taken = 0
internal init (_ baseIterator: Base, _ maxLength: Int) {
precondition(maxLength >= 0, "Can't take a prefix of negative length from an iterator")
self.baseIterator = baseIterator
self.maxLength = maxLength
}
public mutating func next () -> Element? {
if self.taken >= self.maxLength {
return nil
}
self.taken += 1
return self.baseIterator.next()
}
}
...以下顺序,...
public struct LazyPrefixSequence <Base: Sequence>: LazySequenceProtocol {
public typealias Iterator = LazyPrefixIterator<Base.Iterator>
private let baseSequence: Base
private let maxLength: Int
internal init (_ baseSequence: Base, _ maxLength: Int) {
precondition(maxLength >= 0, "Can't take a prefix of negative length from a sequence")
self.baseSequence = baseSequence
self.maxLength = maxLength
}
public func makeIterator() -> Iterator {
return LazyPrefixIterator(self.baseSequence.makeIterator(), self.maxLength)
}
}
...下面合集...
public struct LazyPrefixCollection <Base: Collection>: LazyCollectionProtocol {
public typealias Iterator = LazyPrefixIterator<Base.Iterator>
public typealias Index = Base.Index
public typealias Element = Base.Element
private let baseCollection: Base
private let maxLength: Int
internal init (_ baseCollection: Base, _ maxLength: Int) {
precondition(maxLength >= 0, "Can't take a prefix of negative length from a collection")
self.baseCollection = baseCollection
self.maxLength = maxLength
}
public func makeIterator() -> Iterator {
return LazyPrefixIterator(self.baseCollection.makeIterator(), self.maxLength)
}
public var startIndex: Index {
return self.baseCollection.startIndex
}
public var endIndex: Index {
var maxLength = 0
var index = self.baseCollection.startIndex
let baseCollectionEndIndex = self.baseCollection.endIndex
while maxLength < self.maxLength && index != baseCollectionEndIndex {
index = self.baseCollection.index(after: index)
maxLength += 1
}
return index
}
public func index (after i: Index) -> Index {
precondition(i != self.endIndex, "Can't advance past endIndex")
return self.baseCollection.index(after: i)
}
public subscript (position: Index) -> Element {
precondition(position >= self.startIndex && position < self.endIndex, "Index out of range")
return self.baseCollection[position]
}
}
...以及以下重载(以消除歧义问题),...
public extension LazySequence {
func prefix (_ maxLength: Int) -> LazyPrefixSequence<Elements> {
return LazyPrefixSequence(self.elements, maxLength)
}
}
public extension LazySequenceProtocol {
func prefix (_ maxLength: Int) -> LazyPrefixSequence<Self> {
return LazyPrefixSequence(self, maxLength)
}
}
public extension LazyCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<Base> {
return LazyPrefixCollection(self.elements, maxLength)
}
}
public extension LazyCollectionProtocol {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<Self> {
return LazyPrefixCollection(self, maxLength)
}
}
public extension LazyDropWhileBidirectionalCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<LazyDropWhileBidirectionalCollection<Base>> {
return LazyPrefixCollection(self, maxLength)
}
}
public extension LazyPrefixWhileBidirectionalCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<LazyPrefixWhileBidirectionalCollection<Base>> {
return LazyPrefixCollection(self, maxLength)
}
}
public extension LazyRandomAccessCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<LazyRandomAccessCollection<Base>> {
return LazyPrefixCollection(self, maxLength)
}
}
...以下按预期工作(这些印刷品中的每一个 true
)...
print(Array(AnySequence(sequence(first: 0, next: {[=14=] + 1})).lazy.prefix(2)) == [0, 1])
print(Array(sequence(first: 0, next: {[=14=] + 1}).lazy.drop(while: {_ in false}).prefix(2)) == [0, 1])
print(Array(sequence(first: 0, next: {[=14=] + 1}).lazy.filter{_ in true}.prefix(2)) == [0, 1])
print(Array(sequence(first: 0, next: {[=14=] + 1}).lazy.map{[=14=]}.prefix(2)) == [0, 1])
print(Array(sequence(first: 0, next: {[=14=] + 1}).lazy.prefix(while: {_ in true}).prefix(2)) == [0, 1])
print(Array(sequence(first: 0, next: {[=14=] + 1}).lazy.prefix(2)) == [0, 1])
print(Array(AnyCollection([0, 1, 2]).lazy.prefix(2)) == [0, 1])
print(Array(([0, 1, 2].lazy as LazyBidirectionalCollection).prefix(2)) == [0, 1])
print(Array([0, 1, 2].lazy.drop(while: {_ in false}).prefix(2)) == [0, 1])
print(Array(([0, 1, 2].lazy.drop(while: {_ in false}) as LazyDropWhileCollection).prefix(2)) == [0, 1])
print(Array([0, 1, 2].lazy.filter{_ in true}.prefix(2)) == [0, 1])
print(Array(([0, 1, 2].lazy.filter{_ in true} as LazyFilterCollection).prefix(2)) == [0, 1])
print(Array(([0, 1, 2].lazy.map{[=14=]} as LazyMapBidirectionalCollection).prefix(2)) == [0, 1])
print(Array(([0, 1, 2].lazy.map{[=14=]} as LazyMapCollection).prefix(2)) == [0, 1])
print(Array([0, 1, 2].lazy.map{[=14=]}.prefix(2)) == [0, 1])
print(Array([0, 1, 2].lazy.prefix(while: {_ in true}).prefix(2)) == [0, 1])
print(Array(([0, 1, 2].lazy.prefix(while: {_ in true}) as LazyPrefixWhileCollection).prefix(2)) == [0, 1])
print(Array([0, 1, 2].lazy.prefix(2)) == [0, 1])
...,但是,当在一个集合上多次链接该方法时,会出现奇怪的编译器行为。以下适用于 return 类型的 LazyPrefixCollection<LazyRandomAccessCollection<[Int]>>
:
_ = [0, 1, 2].lazy.prefix(3)
以下也适用,return 类型 LazyPrefixCollection<LazyPrefixCollection<LazyRandomAccessCollection<[Int]>>>
:
_ = [0, 1, 2].lazy.prefix(3).prefix(3)
但是一旦我们添加了另一个方法,它就会出现问题。它告诉我 Expression type '()' is ambiguous without more context
:
_ = [0, 1, 2].lazy.prefix(3).prefix(3).prefix(3)
如果我们添加另一个它在类型检查时会出现段错误:
_ = [0, 1, 2].lazy.prefix(3).prefix(3).prefix(3).prefix(3)
当然,为每个 'step' 创建中间变量有效:
let a = [0, 1, 2].lazy.prefix(3)
let b = a.prefix(3)
let c = b.prefix(3)
let d = c.prefix(3)
// Etc.
还值得注意的是,当我们使用序列而不是集合时它会起作用:
_ = sequence(first: 0, next: {(e: Int) -> Int in e + 1}).lazy.prefix(3).prefix(3).prefix(3).prefix(3).prefix(3)
将多个 map
或标准库中的任何其他方法链接到集合上不会导致任何问题。编译器很高兴地排除了这个怪物:
_ = [0, 1, 2].lazy.map{[=21=]}.map{[=21=]}.map{[=21=]}.map{[=21=]}.map{[=21=]}.map{[=21=]}
这让我相信我的代码有问题,尤其是 LazyPrefixCollection
。
是什么导致了这种行为?
在 LazyPrefixSequence
和 LazyPrefixCollection
上为 prefix(_ maxLength)
添加重载可以解决所有编译器问题。然后代码变成如下:
public struct LazyPrefixIterator <Base: IteratorProtocol>: IteratorProtocol {
public typealias Element = Base.Element
private var baseIterator: Base
private let maxLength: Int
private var taken = 0
internal init (_ baseIterator: Base, _ maxLength: Int) {
precondition(maxLength >= 0, "Can't take a prefix of negative length from an iterator")
self.baseIterator = baseIterator
self.maxLength = maxLength
}
public mutating func next () -> Element? {
if self.taken >= self.maxLength {
return nil
}
self.taken += 1
return self.baseIterator.next()
}
}
public struct LazyPrefixSequence <Base: Sequence>: LazySequenceProtocol {
public typealias Iterator = LazyPrefixIterator<Base.Iterator>
private let baseSequence: Base
private let maxLength: Int
internal init (_ baseSequence: Base, _ maxLength: Int) {
precondition(maxLength >= 0, "Can't take a prefix of negative length from a sequence")
self.baseSequence = baseSequence
self.maxLength = maxLength
}
public func makeIterator() -> Iterator {
return LazyPrefixIterator(self.baseSequence.makeIterator(), self.maxLength)
}
}
public extension LazyPrefixSequence where Base.SubSequence: Sequence {
func prefix (_ maxLength: Int) -> LazyPrefixSequence {
return LazyPrefixSequence(self.baseSequence, Swift.min(self.maxLength, maxLength))
}
}
public struct LazyPrefixCollection <Base: Collection>: LazyCollectionProtocol {
public typealias Iterator = LazyPrefixIterator<Base.Iterator>
public typealias Index = Base.Index
public typealias Element = Base.Element
private let baseCollection: Base
private let maxLength: Int
internal init (_ baseCollection: Base, _ maxLength: Int) {
precondition(maxLength >= 0, "Can't take a prefix of negative length from a collection")
self.baseCollection = baseCollection
self.maxLength = maxLength
}
public func makeIterator() -> Iterator {
return LazyPrefixIterator(self.baseCollection.makeIterator(), self.maxLength)
}
public var startIndex: Index {
return self.baseCollection.startIndex
}
public var endIndex: Index {
var maxLength = 0
var index = self.baseCollection.startIndex
while maxLength < self.maxLength && index != self.baseCollection.endIndex {
index = self.baseCollection.index(after: index)
maxLength += 1
}
return index
}
public func index (after i: Index) -> Index {
precondition(i != self.endIndex, "Can't advance past endIndex")
return self.baseCollection.index(after: i)
}
public subscript (position: Index) -> Element {
precondition(position >= self.startIndex && position < self.endIndex, "Index out of range")
return self.baseCollection[position]
}
public func prefix (_ maxLength: Int) -> LazyPrefixCollection {
return LazyPrefixCollection(self.baseCollection, Swift.min(self.maxLength, maxLength))
}
}
public extension LazySequence {
func prefix (_ maxLength: Int) -> LazyPrefixSequence<Elements> {
return LazyPrefixSequence(self.elements, maxLength)
}
}
public extension LazySequenceProtocol {
func prefix (_ maxLength: Int) -> LazyPrefixSequence<Self> {
return LazyPrefixSequence(self, maxLength)
}
}
public extension LazyCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<Base> {
return LazyPrefixCollection(self.elements, maxLength)
}
}
public extension LazyCollectionProtocol {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<Self> {
return LazyPrefixCollection(self, maxLength)
}
}
public extension LazyDropWhileBidirectionalCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<LazyDropWhileBidirectionalCollection<Base>> {
return LazyPrefixCollection(self, maxLength)
}
}
public extension LazyPrefixWhileBidirectionalCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<LazyPrefixWhileBidirectionalCollection<Base>> {
return LazyPrefixCollection(self, maxLength)
}
}
public extension LazyRandomAccessCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<LazyRandomAccessCollection<Base>> {
return LazyPrefixCollection(self, maxLength)
}
}
正在测试:
let xs = [0, 1, 2, 3, 4].lazy.prefix(3).prefix(10).prefix(100).prefix(10).prefix(5).prefix(1)
let ys = sequence(first: 0, next: {[=11=] + 1}).lazy.prefix(3).prefix(10).prefix(100).prefix(10).prefix(5).prefix(1)
print(Array(xs)) // [0]
print(type(of: xs)) // LazyPrefixCollection<LazyRandomAccessCollection<Array<Int>>>
print(Array(ys)) // [0]
print(type(of: ys)) // LazyPrefixSequence<UnfoldSequence<Int, (Optional<Int>, Bool)>>
感谢反馈。特别是涉及到正确的 typealias
es 和 where
子句时。那些东西对我来说仍然感觉像是武断的巫毒黑魔法;如果我不对 LazyPrefixSequence
添加 where Base.SubSequence: Sequence
限制,那么它会要求我对其他方法进行一大堆无用的重载。为什么 SubSequence
不符合 Sequence
对我来说毫无意义。
我正在尝试通过为所有惰性序列和集合重载 prefix(_ maxLength)
来修复 this bug,但我 运行 遇到了奇怪的编译器问题。
我正在使用 Xcode 9.0 beta 6 (9M214v),但它也可以在 4.0 的所有最新快照中重现。
给定以下迭代器,...
public struct LazyPrefixIterator <Base: IteratorProtocol>: IteratorProtocol {
public typealias Element = Base.Element
private var baseIterator: Base
private let maxLength: Int
private var taken = 0
internal init (_ baseIterator: Base, _ maxLength: Int) {
precondition(maxLength >= 0, "Can't take a prefix of negative length from an iterator")
self.baseIterator = baseIterator
self.maxLength = maxLength
}
public mutating func next () -> Element? {
if self.taken >= self.maxLength {
return nil
}
self.taken += 1
return self.baseIterator.next()
}
}
...以下顺序,...
public struct LazyPrefixSequence <Base: Sequence>: LazySequenceProtocol {
public typealias Iterator = LazyPrefixIterator<Base.Iterator>
private let baseSequence: Base
private let maxLength: Int
internal init (_ baseSequence: Base, _ maxLength: Int) {
precondition(maxLength >= 0, "Can't take a prefix of negative length from a sequence")
self.baseSequence = baseSequence
self.maxLength = maxLength
}
public func makeIterator() -> Iterator {
return LazyPrefixIterator(self.baseSequence.makeIterator(), self.maxLength)
}
}
...下面合集...
public struct LazyPrefixCollection <Base: Collection>: LazyCollectionProtocol {
public typealias Iterator = LazyPrefixIterator<Base.Iterator>
public typealias Index = Base.Index
public typealias Element = Base.Element
private let baseCollection: Base
private let maxLength: Int
internal init (_ baseCollection: Base, _ maxLength: Int) {
precondition(maxLength >= 0, "Can't take a prefix of negative length from a collection")
self.baseCollection = baseCollection
self.maxLength = maxLength
}
public func makeIterator() -> Iterator {
return LazyPrefixIterator(self.baseCollection.makeIterator(), self.maxLength)
}
public var startIndex: Index {
return self.baseCollection.startIndex
}
public var endIndex: Index {
var maxLength = 0
var index = self.baseCollection.startIndex
let baseCollectionEndIndex = self.baseCollection.endIndex
while maxLength < self.maxLength && index != baseCollectionEndIndex {
index = self.baseCollection.index(after: index)
maxLength += 1
}
return index
}
public func index (after i: Index) -> Index {
precondition(i != self.endIndex, "Can't advance past endIndex")
return self.baseCollection.index(after: i)
}
public subscript (position: Index) -> Element {
precondition(position >= self.startIndex && position < self.endIndex, "Index out of range")
return self.baseCollection[position]
}
}
...以及以下重载(以消除歧义问题),...
public extension LazySequence {
func prefix (_ maxLength: Int) -> LazyPrefixSequence<Elements> {
return LazyPrefixSequence(self.elements, maxLength)
}
}
public extension LazySequenceProtocol {
func prefix (_ maxLength: Int) -> LazyPrefixSequence<Self> {
return LazyPrefixSequence(self, maxLength)
}
}
public extension LazyCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<Base> {
return LazyPrefixCollection(self.elements, maxLength)
}
}
public extension LazyCollectionProtocol {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<Self> {
return LazyPrefixCollection(self, maxLength)
}
}
public extension LazyDropWhileBidirectionalCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<LazyDropWhileBidirectionalCollection<Base>> {
return LazyPrefixCollection(self, maxLength)
}
}
public extension LazyPrefixWhileBidirectionalCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<LazyPrefixWhileBidirectionalCollection<Base>> {
return LazyPrefixCollection(self, maxLength)
}
}
public extension LazyRandomAccessCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<LazyRandomAccessCollection<Base>> {
return LazyPrefixCollection(self, maxLength)
}
}
...以下按预期工作(这些印刷品中的每一个 true
)...
print(Array(AnySequence(sequence(first: 0, next: {[=14=] + 1})).lazy.prefix(2)) == [0, 1])
print(Array(sequence(first: 0, next: {[=14=] + 1}).lazy.drop(while: {_ in false}).prefix(2)) == [0, 1])
print(Array(sequence(first: 0, next: {[=14=] + 1}).lazy.filter{_ in true}.prefix(2)) == [0, 1])
print(Array(sequence(first: 0, next: {[=14=] + 1}).lazy.map{[=14=]}.prefix(2)) == [0, 1])
print(Array(sequence(first: 0, next: {[=14=] + 1}).lazy.prefix(while: {_ in true}).prefix(2)) == [0, 1])
print(Array(sequence(first: 0, next: {[=14=] + 1}).lazy.prefix(2)) == [0, 1])
print(Array(AnyCollection([0, 1, 2]).lazy.prefix(2)) == [0, 1])
print(Array(([0, 1, 2].lazy as LazyBidirectionalCollection).prefix(2)) == [0, 1])
print(Array([0, 1, 2].lazy.drop(while: {_ in false}).prefix(2)) == [0, 1])
print(Array(([0, 1, 2].lazy.drop(while: {_ in false}) as LazyDropWhileCollection).prefix(2)) == [0, 1])
print(Array([0, 1, 2].lazy.filter{_ in true}.prefix(2)) == [0, 1])
print(Array(([0, 1, 2].lazy.filter{_ in true} as LazyFilterCollection).prefix(2)) == [0, 1])
print(Array(([0, 1, 2].lazy.map{[=14=]} as LazyMapBidirectionalCollection).prefix(2)) == [0, 1])
print(Array(([0, 1, 2].lazy.map{[=14=]} as LazyMapCollection).prefix(2)) == [0, 1])
print(Array([0, 1, 2].lazy.map{[=14=]}.prefix(2)) == [0, 1])
print(Array([0, 1, 2].lazy.prefix(while: {_ in true}).prefix(2)) == [0, 1])
print(Array(([0, 1, 2].lazy.prefix(while: {_ in true}) as LazyPrefixWhileCollection).prefix(2)) == [0, 1])
print(Array([0, 1, 2].lazy.prefix(2)) == [0, 1])
...,但是,当在一个集合上多次链接该方法时,会出现奇怪的编译器行为。以下适用于 return 类型的 LazyPrefixCollection<LazyRandomAccessCollection<[Int]>>
:
_ = [0, 1, 2].lazy.prefix(3)
以下也适用,return 类型 LazyPrefixCollection<LazyPrefixCollection<LazyRandomAccessCollection<[Int]>>>
:
_ = [0, 1, 2].lazy.prefix(3).prefix(3)
但是一旦我们添加了另一个方法,它就会出现问题。它告诉我 Expression type '()' is ambiguous without more context
:
_ = [0, 1, 2].lazy.prefix(3).prefix(3).prefix(3)
如果我们添加另一个它在类型检查时会出现段错误:
_ = [0, 1, 2].lazy.prefix(3).prefix(3).prefix(3).prefix(3)
当然,为每个 'step' 创建中间变量有效:
let a = [0, 1, 2].lazy.prefix(3)
let b = a.prefix(3)
let c = b.prefix(3)
let d = c.prefix(3)
// Etc.
还值得注意的是,当我们使用序列而不是集合时它会起作用:
_ = sequence(first: 0, next: {(e: Int) -> Int in e + 1}).lazy.prefix(3).prefix(3).prefix(3).prefix(3).prefix(3)
将多个 map
或标准库中的任何其他方法链接到集合上不会导致任何问题。编译器很高兴地排除了这个怪物:
_ = [0, 1, 2].lazy.map{[=21=]}.map{[=21=]}.map{[=21=]}.map{[=21=]}.map{[=21=]}.map{[=21=]}
这让我相信我的代码有问题,尤其是 LazyPrefixCollection
。
是什么导致了这种行为?
在 LazyPrefixSequence
和 LazyPrefixCollection
上为 prefix(_ maxLength)
添加重载可以解决所有编译器问题。然后代码变成如下:
public struct LazyPrefixIterator <Base: IteratorProtocol>: IteratorProtocol {
public typealias Element = Base.Element
private var baseIterator: Base
private let maxLength: Int
private var taken = 0
internal init (_ baseIterator: Base, _ maxLength: Int) {
precondition(maxLength >= 0, "Can't take a prefix of negative length from an iterator")
self.baseIterator = baseIterator
self.maxLength = maxLength
}
public mutating func next () -> Element? {
if self.taken >= self.maxLength {
return nil
}
self.taken += 1
return self.baseIterator.next()
}
}
public struct LazyPrefixSequence <Base: Sequence>: LazySequenceProtocol {
public typealias Iterator = LazyPrefixIterator<Base.Iterator>
private let baseSequence: Base
private let maxLength: Int
internal init (_ baseSequence: Base, _ maxLength: Int) {
precondition(maxLength >= 0, "Can't take a prefix of negative length from a sequence")
self.baseSequence = baseSequence
self.maxLength = maxLength
}
public func makeIterator() -> Iterator {
return LazyPrefixIterator(self.baseSequence.makeIterator(), self.maxLength)
}
}
public extension LazyPrefixSequence where Base.SubSequence: Sequence {
func prefix (_ maxLength: Int) -> LazyPrefixSequence {
return LazyPrefixSequence(self.baseSequence, Swift.min(self.maxLength, maxLength))
}
}
public struct LazyPrefixCollection <Base: Collection>: LazyCollectionProtocol {
public typealias Iterator = LazyPrefixIterator<Base.Iterator>
public typealias Index = Base.Index
public typealias Element = Base.Element
private let baseCollection: Base
private let maxLength: Int
internal init (_ baseCollection: Base, _ maxLength: Int) {
precondition(maxLength >= 0, "Can't take a prefix of negative length from a collection")
self.baseCollection = baseCollection
self.maxLength = maxLength
}
public func makeIterator() -> Iterator {
return LazyPrefixIterator(self.baseCollection.makeIterator(), self.maxLength)
}
public var startIndex: Index {
return self.baseCollection.startIndex
}
public var endIndex: Index {
var maxLength = 0
var index = self.baseCollection.startIndex
while maxLength < self.maxLength && index != self.baseCollection.endIndex {
index = self.baseCollection.index(after: index)
maxLength += 1
}
return index
}
public func index (after i: Index) -> Index {
precondition(i != self.endIndex, "Can't advance past endIndex")
return self.baseCollection.index(after: i)
}
public subscript (position: Index) -> Element {
precondition(position >= self.startIndex && position < self.endIndex, "Index out of range")
return self.baseCollection[position]
}
public func prefix (_ maxLength: Int) -> LazyPrefixCollection {
return LazyPrefixCollection(self.baseCollection, Swift.min(self.maxLength, maxLength))
}
}
public extension LazySequence {
func prefix (_ maxLength: Int) -> LazyPrefixSequence<Elements> {
return LazyPrefixSequence(self.elements, maxLength)
}
}
public extension LazySequenceProtocol {
func prefix (_ maxLength: Int) -> LazyPrefixSequence<Self> {
return LazyPrefixSequence(self, maxLength)
}
}
public extension LazyCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<Base> {
return LazyPrefixCollection(self.elements, maxLength)
}
}
public extension LazyCollectionProtocol {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<Self> {
return LazyPrefixCollection(self, maxLength)
}
}
public extension LazyDropWhileBidirectionalCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<LazyDropWhileBidirectionalCollection<Base>> {
return LazyPrefixCollection(self, maxLength)
}
}
public extension LazyPrefixWhileBidirectionalCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<LazyPrefixWhileBidirectionalCollection<Base>> {
return LazyPrefixCollection(self, maxLength)
}
}
public extension LazyRandomAccessCollection {
func prefix (_ maxLength: Int) -> LazyPrefixCollection<LazyRandomAccessCollection<Base>> {
return LazyPrefixCollection(self, maxLength)
}
}
正在测试:
let xs = [0, 1, 2, 3, 4].lazy.prefix(3).prefix(10).prefix(100).prefix(10).prefix(5).prefix(1)
let ys = sequence(first: 0, next: {[=11=] + 1}).lazy.prefix(3).prefix(10).prefix(100).prefix(10).prefix(5).prefix(1)
print(Array(xs)) // [0]
print(type(of: xs)) // LazyPrefixCollection<LazyRandomAccessCollection<Array<Int>>>
print(Array(ys)) // [0]
print(type(of: ys)) // LazyPrefixSequence<UnfoldSequence<Int, (Optional<Int>, Bool)>>
感谢反馈。特别是涉及到正确的 typealias
es 和 where
子句时。那些东西对我来说仍然感觉像是武断的巫毒黑魔法;如果我不对 LazyPrefixSequence
添加 where Base.SubSequence: Sequence
限制,那么它会要求我对其他方法进行一大堆无用的重载。为什么 SubSequence
不符合 Sequence
对我来说毫无意义。