【问题标题】:How does return statement work in switch?return 语句在 switch 中是如何工作的?
【发布时间】:2016-04-16 05:26:59
【问题描述】:

下面的代码创建了一个计算器,它记住了所有的操作数和运算符。“Evaluate”函数接受一个 Ops 数组并返回一个包含结果和剩余操作的元组。但我无法理解 switch 发生了什么.

如果情况是 opStack 有 4,x,5,+,6 最后一个元素 6 被删除并检查,在 switch 中。由于它是一个操作数,它将返回 6(操作数)和其余的元素 4,x,5,+。

我的理解正确吗? "6" 和 "4,x,5,+" 去哪里了,整个表达式如何计算?

         private enum Op {
    case Operand (Double)
    case UnaryOperation(String , Double -> Double)
    case BinaryOperation(String , (Double,Double) -> Double)
        }
private var opStack = [Op]()
private var knownOps = [String : Op]()

init() {
    knownOps["×"] = Op.BinaryOperation("×" , *)
    knownOps["÷"] = Op.BinaryOperation("÷" ){ $1 / $0 }
    knownOps["+"] = Op.BinaryOperation("+" , +)
    knownOps["−"] = Op.BinaryOperation("−" ){ $1 - $0 }
    knownOps["√"] = Op.UnaryOperation("√" ,sqrt)
}

   private func evaluate( ops : [Op]) -> (result : Double? , remainingOps: [Op]){

    if !ops.isEmpty {
        var remainingOps = ops
        let op = remainingOps.removeLast()

        switch op{

        case .Operand(let operand):
            return (operand , remainingOps)

        case .UnaryOperation( _ , let operation):
            let operandEvaluation = evaluate(remainingOps)
         if let operand = operandEvaluation.result{
            return ( operation(operand), operandEvaluation.remainingOps) }

}
        case .BinaryOperation(_, let operation):
            let op1Evaluation = evaluate(remainingOps)
            if let operand1 = op1Evaluation.result {
                let op2Evaluation = evaluate(op1Evaluation.remainingOps)
                if let operand2 = op2Evaluation.result {
                    return (operation(operand1, operand2), op2Evaluation.remainingOps)
                }
            }
        }
          }
    return(nil , ops)
}

【问题讨论】:

  • 函数是递归的;请注意UnaryOperationBinaryOperation 案例调用evaluate。您可以设置断点并单步执行该函数以查看它是如何工作的,但是当您说操作数堆栈中有 4,x,5,+,6 时,我怀疑您是不正确的。看起来它会有两个操作“4x5”和“+6”

标签: ios swift recursion switch-statement return


【解决方案1】:

啊,你正在做斯坦福的快速讲座!他们都是伟大的。当我浏览它们时,我也遇到了这个功能的一些问题。

基本上,计算器的工作方式非常不典型,作为用户正确使用它需要一点时间。在这种情况下,调用堆栈将返回 6,您是绝对正确的。然后用户可以再次评估,但是您的调用堆栈将无法正常工作。

计算器期望此流程用于二元运算:

用户输入操作数 1 并将其添加到堆栈中 用户输入操作数 2 并将其添加到堆栈中。 然后用户输入他们想要应用于操作数的二元运算符

所以二进制操作的调用堆栈如下所示:

[5,6,*]

这将评估为 30

对于它期望的一元运算:

用户输入操作数并将其添加到堆栈中 用户选择他们想应用于操作数的一元操作

所以一元调用堆栈看起来像:

[4,√]

计算结果为 2

它是这样工作的,在堆栈中没有操作之前的操作数将结束评估运行,因为否则它将无法理解堆栈的其余部分(查看您的堆栈并将其与计算器的预期值进行比较你会明白我的意思)

与@paulw11 一样,我强烈建议在评估开始时设置断点并逐步(非常缓慢地)运行它,因为了解它的工作原理非常有用。

【讨论】:

  • 谢谢,这有帮助。 y)
猜你喜欢
  • 2012-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多