Reputation: 1498
According to the documentation:
init(_ s: S) where Element == S.Element, S : Sequence
Creates an array containing the elements of a sequence.
struct Test: IteratorProtocol, Sequence {
let id: Int
init(_ id: Int) {
self.id = id
}
mutating func next() -> Test? {
id < 10 ? Test(id + 1) : nil
}
}
let test = Test(5)
let arr = Array(test)
It compiles. And doesn't even throw any runtime errors.
But instead of getting the array [5, 6, 7, 8, 9] as a result, I get an infinite loop! next()
is called infinitely many times.
I thought that nil
in next()
is a natural indicator of the end of sequence. But apparently it's not.
Upvotes: 1
Views: 3694
Reputation: 1498
Appears, there is a built-in function, that completely suits the logic of my initial question in this post.
sequence(first:next:)
Returns a sequence formed from first and repeated lazy applications of next.
struct Test {
var id: Int
init(_ id: Int) {
self.id = id
}
}
let seq = sequence(first: Test(5), next: { test in
let id = test.id + 1
return id < 10 ? Test(id) : nil
})
let arr = Array(seq)
Upvotes: 0
Reputation: 2908
It should be something like this
struct Test: IteratorProtocol, Sequence {
var id: Int
init(_ id: Int) {
self.id = id
}
mutating func next() -> Test? {
defer { id += 1 }
return id < 10 ? self : nil
}
}
print(Array(Test(6)))
Another example
struct Countdown: Sequence, IteratorProtocol {
var count: Int
mutating func next() -> Int? {
if count == 0 {
return nil
} else {
defer { count -= 1 }
return count
}
}
}
let threeToGo = Countdown(count: 3)
for i in threeToGo {
print(i)
}
// Prints "3"
// Prints "2"
// Prints "1"
Upvotes: 1