Swift 如果包含某些内容,则展开(可选)

Swift 如果包含某些内容,则展开(可选),swift,do-while,Swift,Do While,上下文:我有一个通用的对象堆栈。堆栈响应pop()(返回一个可选值),我有一个函数需要处理堆栈 如果堆栈为空,则抛出错误 否则,重复操作,直到下一个可选项不可打开 到目前为止 guard var nextVar = myStack.pop() else { throw MyError.EmptyStack } repeat { // Process nextVar } while nextVar = myStack.pop() 问题:第一个nextVar不是可选的,因此我的

上下文:我有一个通用的对象堆栈。堆栈响应pop()(返回一个可选值),我有一个函数需要处理堆栈

  • 如果堆栈为空,则抛出错误
  • 否则,重复操作,直到下一个可选项不可打开
到目前为止

guard var nextVar = myStack.pop() else {
   throw MyError.EmptyStack
}

repeat {
    // Process nextVar
} while nextVar = myStack.pop()

问题:第一个nextVar不是可选的,因此我的while调用失败。如何重写,以便while检查可选项是否包含某些内容,如果成功,则将内容分配给变量?()

您应该修改堆栈类型以包含
isEmpty
属性。这样您就不需要重复
pop
调用,这将是一个简单的
while let
循环

guard !myStack.isEmpty else {
   throw MyError.EmptyStack
}

while let nextVar = myStack.pop() {
    // Process nextVar
}

您还可以将其转换为
序列类型
,但迭代不会消耗堆栈。那么这就是:

guard !myStack.isEmpty else {
   throw MyError.EmptyStack
}

for nextVar in myStack {
    // Process nextVar
}
由于
pop
正是
GeneratorType.next()
所需的实现,因此应该很容易将其转换为
GeneratorType
SequenceType
(通过在
generate()
中返回
self

但是由于
Stack
是一种值类型,因此在
中使用
for对其进行迭代将生成一个副本,然后使用该副本,而不是使用原始堆栈。这可能是好的,也可能是坏的

这是我的意思的草图:

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
    }
}
struct堆栈{
私有变量堆栈:[Element]=[]
变异函数推送(元素:元素){
stack.append(元素)
}
变异func pop()->元素{
guard let result=stack.last else{return nil}
stack.removeLast()
返回结果
}
var isEmpty:Bool{return stack.isEmpty}
}
扩展堆栈:GeneratorType{
突变func next()->元素{
返回pop()
}
}
扩展堆栈:SequenceType{
func generate()->Stack{
回归自我
}
}

次要备注:如果同时采用SequenceType和GeneratorType,则不必实现generate(),这是一个默认实现。