Swift 为什么下一步变异函数在迭代后不改变结构(符合序列和迭代协议)?

Swift 为什么下一步变异函数在迭代后不改变结构(符合序列和迭代协议)?,swift,sequence,mutating-function,iterator-protocol,Swift,Sequence,Mutating Function,Iterator Protocol,我编写了一个堆栈结构,并使其符合IteratorProtocol和Sequence协议。next函数正在变异。因此,我认为堆栈的迭代将改变结构 import Foundation struct Stack<Element> { var store:[Element] = [] mutating func push(_ element:Element) { store.append(element) } mutating func

我编写了一个堆栈结构,并使其符合
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)
<代码>导入基础 结构堆栈{ 变量存储:[Element]=[] 变异函数推送(u元素:元素){ store.append(元素) } 变异func pop()->元素{ return store.popLast() } } 扩展堆栈:序列,迭代协议{ 突变func next()->元素{ 返回pop() } } var stack=stack() 堆栈推送(1) 堆栈推送(2) 堆栈推送(3) 对于堆栈中的{ 印刷品 } 打印(堆栈) 以下是控制台输出:


我不明白为什么堆栈是不变的。我想在调用了mutating
next()
之后,它会变成空的。

您的
for。。。在
-循环在堆栈的副本上工作,从不更改堆栈本身。如果您自己调用
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)

然而,正如@user3581248在注释中指出的那样,将堆栈作为类而不是结构(并从其函数中删除
mutating
)可以提供所需的行为

您从不调用
next()
。如果您愿意,输出将变成
2\n1\n堆栈(存储:[1,2])
@Mr.Xcoder这是一个可怕的错误suggestion@user3581248调用您定义的函数并不是“非常错误的建议”。事实上,公认的答案就是这样。当然,将其更改为类要方便得多,但我的并不是“可怕的错误”。我只想建议不要调用
next()
。@Mr.Xcoder当您在堆栈上迭代时,会调用它。这就是实现
IteratorProtocol
的全部要点。接受答案的要点是在第一句话中。答案正确,但您也可以添加,将
堆栈
类型更改为类将给出预期的行为将结构更改为类告诉一切。多谢各位@user3581248@user3581248是的,我在答案中加上了你的话,以提高可见度。
3
2
1
[1, 2]