Почему мутирующая функция next не изменяет структуру (в соответствии с Sequence и IteratorProtocol) после итерации?

Я пишу стековую структуру и делаю ее соответствующей IteratorProtocol а также Sequence протокол. next функция мутирует. Так что я полагаю, что итерация стека приведет к изменению структуры.

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)

Вот вывод консоли:

Я не понимаю, почему стек не изменился. Я полагаю, что он стал пустым после мутации next() звонки.

1 ответ

Решение

Ваш for ... in-Coop работает с копией стека и никогда не меняет сам стек. Если бы вы должны были позвонить next() себя pop() изменил бы стек, как вы можете видеть здесь:

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)

Выход:

3
2
1
[1, 2]

Однако, как указал @user3581248 в комментариях, Stack становится классом вместо struct (и удаляется mutating от его функций) дает вам желаемое поведение.

Другие вопросы по тегам