0

我正在 iTunesU 上学习 CS193P 课程。我有一个与第一个作业有关的问题 - 可编程计算器。我尝试按照讲座和家庭作业中的说明添加 π 按钮。但是,按 π 键后跟 enter or 和操作数会导致崩溃并显示以下消息:“致命错误:在展开可选值时意外发现 nil”

class CalculatorBrain
{
private enum Op {
    case Operand(Double)
    case NullaryOperation(String, () -> Double)
    case UnaryOperation(String, Double -> Double)
    case BinaryOperation(String, (Double,Double) -> Double)

    var description: String{
        get {
            switch self {
            case .Operand(let operand): return "\(operand)"
            case .NullaryOperation(let symbol, _): return symbol
            case .UnaryOperation(let symbol, _): return symbol
            case .BinaryOperation(let symbol,_):return symbol
            }
        }
    }
}

private var opStack = [Op]()

private var knownOps = [String:Op]() //initialize dictionary

init() {
    func learnOp (op: Op) {
        knownOps[op.description] = op
    }
    learnOp(Op.BinaryOperation("×", *))
    learnOp(Op.BinaryOperation("÷", { $1 / $0 }))
    learnOp(Op.BinaryOperation("+", +))
    learnOp(Op.BinaryOperation("−", { $1 - $0 }))
    learnOp(Op.UnaryOperation("√", sqrt))
    learnOp(Op.UnaryOperation("sin", sin))
    learnOp(Op.UnaryOperation("cos", cos))
    learnOp(Op.NullaryOperation("π", { M_PI }))
}

我已经能够在视图控制器中强制它,但知道这是一个 hack:

var displayValue: Double{
    get{
        // I don't understand why I had to put this hack in for π
      //  if (calcDisplay.text != "π"){
            return NSNumberFormatter().numberFromString(calcDisplay.text!)!.doubleValue
       // } else {
       // return M_PI
       // }
    }
    set{
        calcDisplay.text = "\(newValue)"
        userIsInTheMiddleOfTyping = false
    }
}

我是 Swift / Obj-C 的新手。有人可以帮我指出正确的方向来解决这个问题吗?

完整来源:https ://github.com/philnewman/Calculator

4

4 回答 4

1
@IBAction func appendPi(sender: UIButton) {

    let x = M_PI
    if userIsInTheMiddleOfTypingANumber {
        displayValue = x
        display.text = "\(displayValue)"
    }else {
        displayValue = x
        userIsInTheMiddleOfTypingANumber = true
        enter()
    }
}

为 PI 创建了一个与其他函数分开的新 UIButton 函数。为我工作,试一试。

于 2015-07-27T21:21:02.813 回答
0

NSNumberFormatter().numberFromString旨在将数字字符串转换为数字。“数字字符串”是一个字符串,其内容的形式为:

([:digit:]+(\.[:digit:]*)?)|(\.[:digit:]+)

[:digit:]数字集在哪里{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

本质上,它只会解析字符在其中的字符串中的数字0-9和一个可选的..

因为π不属于这 10 个字符的集合,所以它被拒绝并且NSNumberFormatter无法从字符串中解析出一个数字。

于 2015-02-15T19:15:50.017 回答
0

我正在做同样的课程,但由于我还没有分离我的 MVC(将在下一个作业中这样做),我只能给你一个提示,你哪里出错了。因为它对我有用....

您的 hack 正在将 calcDisplay.text 测试为“π”,但是此时 calcDisplay.text 应该已经是 3,14159。这就是我在工作任务中使用 println 检查的内容。

因此,我可以向您展示我的部分代码,这对于 MVC 来说还不是最佳的:

   case "cos": performOperation{cos($0)}
    case "∏": performConstant(operation)

func performOperation (operation: (Double) -> Double) {
    if operandStack.count >= 1 {
        displayValue = operation(operandStack.removeLast())
        enter()
    }
}

func performConstant (symbol: (String)) {
    switch symbol {
    case "∏": displayValue = M_PI
    default: break
    }
    display.text = "\(displayValue)"
    enter()
}

我认为它也可以更优化,但它可能会帮助您找到代码中的错误。

于 2015-03-08T18:42:40.817 回答
0

我也在做同样的课程。我确实解决了“。” 和“馅饼”问题。看看这是否对你有帮助。

@IBAction func appendDigit(sender: UIButton) {
        let digit = sender.currentTitle!        
        if digit == "." {

            if (display.text!.rangeOfString(".") == nil) {
                display.text = display.text! + "."


            } else {
                //Don't display anything
            }
        } else if digit == "∏" {
            displayValue = pie
        } else {
                if userIsInTheMiddleOfTypingANumber {
                    display.text = display.text! + digit
                } else {
                    display.text = digit
                    userIsInTheMiddleOfTypingANumber = true
                }
        }
    }
于 2015-06-17T15:06:01.137 回答