1

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()调用之后它会变空。

4

1 回答 1

2

您的for ... in-Loop 在堆栈的副本上工作,并且永远不会更改堆栈本身。如果您要调用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 成为一个类而不是一个结构(并mutating从它的函数中删除)会给你想要的行为。

于 2017-06-27T07:09:14.880 回答