上下文:我有一个通用的对象堆栈。堆栈响应pop()(返回一个可选项),我有一个需要处理堆栈的函数
到目前为止
guard var nextVar = myStack.pop() else {
throw MyError.EmptyStack
}
repeat {
// Process nextVar
} while nextVar = myStack.pop()
问题:第一个nextVar不是可选的,因此我的while调用失败。如何重写以便while检查可选项是否包含某些东西,如果成功,则将内容分配给变量? ()
答案 0 :(得分:3)
您应该修改堆栈类型以包含isEmpty
属性。然后,您无需复制pop
调用,这将是一个简单的while-let
循环。
guard !myStack.isEmpty else {
throw MyError.EmptyStack
}
while let nextVar = myStack.pop() {
// Process nextVar
}
您也可以将其转换为SequenceType
,但迭代不会消耗堆栈。那就是:
guard !myStack.isEmpty else {
throw MyError.EmptyStack
}
for nextVar in myStack {
// Process nextVar
}
由于pop
正是GeneratorType.next()
所需的实现,因此应该很容易将其转换为GeneratorType
和SequenceType
(通过返回self
在generate()
)。
但是由于Stack
是一个值类型,用for-in
迭代它会生成一个副本然后使用该副本,而不是消耗原始堆栈。这可能是好事还是坏事。
这是我的意思草图:
struct Stack<Element> {
private var stack: [Element] = []
mutating func push(element: Element) {
stack.append(element)
}
mutating func pop() -> Element? {
guard let result = stack.last else { return nil }
stack.removeLast()
return result
}
var isEmpty: Bool { return stack.isEmpty }
}
extension Stack: GeneratorType {
mutating func next() -> Element? {
return pop()
}
}
extension Stack: SequenceType {
func generate() -> Stack {
return self
}
}