I write a stack struct, and make it conforming to IteratorProtocol
and Sequence
protocol. The next
function is mutating. So I suppose the iteration of the stack will mutate the struct.
import Foundation
struct Stack<Element> {
var store:[Element] = []
mutating func push(_ element:Element) {
store.append(element)
}
mutating func pop() -> Element? {
return store.popLast()
}
}
extension Stack: Sequence, IteratorProtocol {
mutating func next() -> Element? {
return pop()
}
}
var stack = Stack<Int>()
stack.push(1)
stack.push(2)
stack.push(3)
for s in stack {
print(s)
}
print(stack)
I don't understand why the stack is unchanged. I suppose it become empty after the mutating next()
calls.
Your for ... in
-Loop works on a copy of stack and never changes the stack itself. If you were to call next()
yourself, the pop()
would modify the stack as you can see here:
import Foundation
struct Stack<Element> {
var store: [Element] = []
mutating func push(_ element:Element) {
store.append(element)
}
mutating func pop() -> Element? {
return store.popLast()
}
}
extension Stack: Sequence, IteratorProtocol {
mutating func next() -> Element? {
return pop()
}
}
var stack = Stack<Int>()
stack.push(1)
stack.push(2)
stack.push(3)
for s in stack {
print(s)
}
stack.next()
print(stack.store)
Output:
3
2
1
[1, 2]
However as @user3581248 pointed out in the comments, making Stack a class instead of a struct (and removing mutating
from its functions) gives you the desired behavior.