2017-06-23 17 views
1

在具有錯誤的視圖文件中的行是:
顯示器= brain.evaluateWithErrorReport(使用:dictionaryForVaribles)displays = brain.evaluateWithErrorReport(using:dictionaryForVaribles)給出一個錯誤,除非一個as!被添加。爲什麼?

我接收是錯誤:

/Users/Tom/Developer/Stsnford-IOS 10 Course/Calculator_IOS10/Calculator_IOS10/ViewController.swift:166:26: Cannot assign value of type '(result: Double?, isPending: Bool, description: String, errorDescription: String?)' (aka '(result: Optional<Double>, isPending: Bool, description: String, errorDescription: Optional<String>)') to type '(result: Double, isPending: Bool, sequence: String, errorMessage: String?)' (aka '(result: Double, isPending: Bool, sequence: String, errorMessage: Optional<String>)') 

編譯器說,修復是要加上: as! (result:double,isPending:Bool,sequence:String,errorMessage:String?)

所以現在看起來像這樣: displays = brain.evaluateWithErrorReport(using:dictionaryForVaribles)as! (result:double,isPending:Bool,sequence:String,errorMessage:String?)

爲什麼沒有as! ?

該程序有兩個文件,它是iTunes上CS193P的作業2。

查看文件:

// 
// ViewController.swift 
// Calculator_IOS10 
// 
// Created by Theophilos Aravanis on 4/12/17. 
// Copyright © 2017 Theophilos Aravanis. All rights reserved. 
// 

import UIKit 

class ViewController: UIViewController { 

    @IBOutlet weak var calculatorDisplay: UILabel! 

    @IBOutlet weak var discriptionDisplay: UILabel! 

    @IBOutlet weak var varibleDisplay: UILabel! 



    var displays: (result: Double, isPending:Bool, sequence:String, errorMessage:String?) { 

     get { 

      return (Double(calculatorDisplay.text!)!, false, discriptionDisplay.text!, nil) 

     } 

     set { 

      if newValue.errorMessage != " " { 
       calculatorDisplay.text = newValue.errorMessage 
      } else { 
       let formatter = NumberFormatter() 
       formatter.numberStyle = .decimal 
       formatter.maximumFractionDigits = 6 
       calculatorDisplay.text = formatter.string(from:(NSNumber(value:newValue.result))) 
      } 
      if newValue.sequence.isEmpty { 
       discriptionDisplay.text = " " 
      } else { 
       discriptionDisplay.text = newValue.sequence + (brain.resultIsPending ? " …" : " =") 
      } 

      if let varibaleValue = dictionaryForVaribles["M"] { 
       let formatter = NumberFormatter() 
       formatter.numberStyle = .decimal 
       formatter.maximumFractionDigits = 6 
       varibleDisplay.text = formatter.string(from:(NSNumber(value:varibaleValue))) 
      } else { 
       varibleDisplay.text = " " 
      } 

     } // end of set 
    } 

    var userInMiddleOfTyping = false 

    var currentDisplay = " " 

    var dictionaryForVaribles = [String:Double]() 

    @IBAction func digitTouched(_ sender: UIButton) { 

     let digit = sender.currentTitle! 
     if userInMiddleOfTyping { 
      let currentlyDisplayedText = calculatorDisplay.text! 
      switch digit { 
      case ".": 
       if currentlyDisplayedText.contains("."){ 
        calculatorDisplay.text = currentlyDisplayedText 
       } 
       else { 
        calculatorDisplay.text = currentlyDisplayedText + digit 
       } 
      case "BS": 
       currentDisplay = calculatorDisplay.text! 
       if currentDisplay.isEmpty == false { 
        currentDisplay.remove(at: currentDisplay.index(before: currentDisplay.endIndex)) 
        if currentDisplay.isEmpty { 
         calculatorDisplay.text = "0" 
         userInMiddleOfTyping = false 
        } else { 
         calculatorDisplay.text = currentDisplay 
         userInMiddleOfTyping = true 
        } 
       } 
      default: 
       calculatorDisplay.text = currentlyDisplayedText + digit 
      } 
     } 
     else { 
      switch digit { 
      case "bs": 
       break 
      default: 
       calculatorDisplay.text = digit 
       userInMiddleOfTyping = true 
      } 
     } 
    } 

    /* var displayValue:Double{ 
     get { 
      return Double(calculatorDisplay.text!)! 

     } 
     set { 
      let formatter = NumberFormatter() 
      formatter.numberStyle = .decimal 
      formatter.maximumFractionDigits = 6 
      calculatorDisplay.text = formatter.string(from:(NSNumber(value:newValue))) 
     } 
    } 
    var displayDescription:String{ 
     get { 
       return discriptionDisplay.text! 
     } 
     set { 
      discriptionDisplay.text = newValue + (brain.resultIsPending ? " …" : " =") 
     } 
    } */ 
    private var brain = CalculatorBrain() 

    func showDescriptionDisplay() { 
     discriptionDisplay.isHidden = false 
    } 
    func hideDescriptionDisplay() { 
     discriptionDisplay.isHidden = true 
    } 

    func showVaribleDisplay() { 
     varibleDisplay.isHidden = false 
    } 

    func hideVaribleDisplay() { 
     varibleDisplay.isHidden = true 
    } 

    @IBAction func allClear(_ sender: UIButton) { 
     hideDescriptionDisplay() 
     discriptionDisplay.text = " " 
     calculatorDisplay.text = "0" 
     userInMiddleOfTyping = false 
     brain.clearAccumulator() 
    } 

    @IBAction func setVarible(_ sender: UIButton) { 
     let symbol = sender.currentTitle! 
     brain.setOperand(variable:symbol) 
    } 

    @IBAction func evaluateVarible(_ sender: UIButton) { 
    } 

    @IBAction func performOperation(_ sender: UIButton) { 
     showDescriptionDisplay() 
     if userInMiddleOfTyping { 
      brain.setOperand(displays.result) 
      userInMiddleOfTyping = false 
     } 
     if let mathimaticalSymbol = sender.currentTitle { 
      brain.performOperation(mathimaticalSymbol) 
     } 

     displays = brain.evaluateWithErrorReport(using: dictionaryForVaribles) as! (result: Double, isPending: Bool, sequence: String, errorMessage: String?) 


/*  if let result = brain.result { 
      displays.result = result 
     } 
//  if let descriptionLine = brain.line { 
//   displays.sequence = descriptionLine 
//  } */ 
    } 
} 

模型文件:

// 
// CalculatorBrain_IOS10.swift 
// Calculator_IOS10 
// 
// Created by Theophilos Aravanis on 4/14/17. 
// Copyright © 2017 Theophilos Aravanis. All rights reserved. 
// 

import Foundation 

func factorial(_ op1: Double) -> Double { 
    if (op1 <= 1.0) { 
     return 1.0 
    } 
    return op1 * factorial(op1 - 1.0) 
} 




struct CalculatorBrain { 


    var result:Double? { 
     get { 
      return accumulator?.0 
     } 
    } 

// @available(*, deprecated, message: "Use evaluate instead") 
    var resultIsPending = false 


    private var accumulator:(digit:Double, description:String?, errorMessage:String?)? 

    private enum MemoryVarible { 
     case operand(Double) 
     case operation(String) 
     case variable(String) 
    } 

    private var memorySequence = [MemoryVarible]() 

    private enum Operation { 
     case constant(Double) 
     case nullOperation(() -> Double, String) 
     case unaryOperation((Double) -> Double, (String) -> String, (Double) -> String?) 
     case binaryOperation((Double,Double) -> Double, (String, String) -> String, (Double,Double) -> String?) 
     case equals 
    } 
    private var operations:Dictionary<String,Operation> = 
     [ 
      "rand": .nullOperation({Double(arc4random())/Double(UInt32.max)}, "rand()"), 
      "π" : .constant(M_PI), 
      "e" : .constant(M_E), 
      "√" : .unaryOperation(sqrt,{"√(" + $0 + ")"},{$0 < 0 ? "Sqrt of negative number" : nil}), 
      "cos" :.unaryOperation(cos,{"cos(" + $0 + ")"},{ _ in nil}), 
      "∓" : .unaryOperation({-$0},{"-(" + $0 + ")"},{ _ in nil}), 
      "x²" :.unaryOperation({ pow($0, 2) }, { "(" + $0 + ")²" },{ _ in nil}), 
      "x³" :.unaryOperation({ pow($0, 3) }, { "(" + $0 + ")³" },{ _ in nil}), 
      "x⁻¹" :.unaryOperation({ 1/$0 }, { "(" + $0 + ")⁻¹" },{ _ in nil}), 
      "sin" :.unaryOperation(sin, { "sin(" + $0 + ")" },{ _ in nil}), 
      "tan" :.unaryOperation(tan, { "tan(" + $0 + ")" },{ _ in nil}), 
      "sinh" :.unaryOperation(sinh, { "sinh(" + $0 + ")" },{ _ in nil}), 
      "cosh" :.unaryOperation(cosh, { "cosh(" + $0 + ")" },{ _ in nil}), 
      "tanh" :.unaryOperation(tanh, { "tanh(" + $0 + ")" },{ _ in nil}), 
      "ln" : .unaryOperation(log, { "ln(" + $0 + ")" },{ _ in nil}), 
      "log" : .unaryOperation(log10, { "log(" + $0 + ")" },{ _ in nil}), 
      "eˣ" :.unaryOperation(exp, { "e^(" + $0 + ")" },{ _ in nil}), 
      "10ˣ" :.unaryOperation({ pow(10, $0) }, { "10^(" + $0 + ")" },{ _ in nil}), 
      "x!" :.unaryOperation(factorial, { "(" + $0 + ")!" },{ _ in nil}), 
      "xʸ" :.binaryOperation(pow, { $0 + "^" + $1 },{ _,_ in nil}), 
      "+" : .binaryOperation(+,{$0 + "+" + $1},{ _,_ in nil}), 
      "−" : .binaryOperation(-,{$0 + "-" + $1},{ _,_ in nil}), 
      "÷" : .binaryOperation(/,{$0 + "÷" + $1}, {_,_ in nil }), 
      "×" : .binaryOperation(*,{$0 + "*" + $1},{ _,_ in nil}), 
      "=" : .equals 
    ] 

    mutating func clearAccumulator() { 
     accumulator?.errorMessage = nil 
     accumulator?.description = " " 
     accumulator?.digit = 0 
    } 

    mutating func evaluate(using variables: Dictionary<String,Double>? = nil) -> (result: Double?, isPending: Bool, description: String) { 

     let (result, isPending, description, _) = evaluateWithErrorReport(using: variables) 

     return (result, isPending, description) 

    } 

    mutating func performOperation(_ symbol: String) { 
     memorySequence.append(MemoryVarible.operation(symbol)) 
    } 

    mutating func setOperand(_ operand: Double) { 
     memorySequence.append(MemoryVarible.operand(operand)) 
    } 

    mutating func setOperand(variable named: String) { 
     memorySequence.append(MemoryVarible.variable(named)) 
    } 

    mutating func evaluateWithErrorReport(using variables: Dictionary<String,Double>? = nil) -> (result: Double?, isPending: Bool, description: String, errorDescription: String?) { 

     var pendingBinaryOperation:PendingBinaryOperation? 

     var calculationDescription:String? { 
      get { 
       if pendingBinaryOperation == nil { 
        return accumulator?.description 
       } else { 
        return pendingBinaryOperation!.calculationDescription(pendingBinaryOperation!.descriptionOperand, accumulator?.description ?? " ") 
       } 
      } 
     } 

     var line:String? { 
      get { 
       return calculationDescription 
      } 
     } 

     func performOperation(_ symbol:String){ 
      if let currentOperation = operations[symbol] { 
       switch currentOperation { 
       case .nullOperation(let function, let nullDiscription): 
        accumulator = (function(), nullDiscription, nil) 
       case .constant(let value): 
        accumulator = (value,symbol, nil) 
       case .unaryOperation(let function, let unaryDescription, let unaryMemory): 
        if accumulator != nil { 
         accumulator = (function(accumulator!.digit), unaryDescription(accumulator!.description!), 
             unaryMemory(accumulator!.digit)) 
        } 
       case .binaryOperation(let binaryFunction, 
             let binaryDescription, 
             let binaryError): 
        if accumulator != nil { 
         doAPendingBinaryOperation() 
         resultIsPending = true 
         pendingBinaryOperation = PendingBinaryOperation(
          calculationError:binaryError, 
          mathFunction: binaryFunction, 
          calculationDescription:binaryDescription, 
          firstOperand: accumulator!.digit, 
          descriptionOperand:(accumulator?.description)!) 
         accumulator = nil 
        } 
       case .equals: 
        doAPendingBinaryOperation() 
        resultIsPending = false 
       } 
      } 
     } 

     func doAPendingBinaryOperation() { 
      if pendingBinaryOperation != nil && accumulator != nil { 
       accumulator!.description = calculationDescription! 
       accumulator!.digit = pendingBinaryOperation!.perform(with: accumulator!.digit) 
       accumulator!.errorMessage = "Future enhancement" 
       pendingBinaryOperation = nil 
      } 

     } 

     struct PendingBinaryOperation { 
      let calculationError: (Double, Double) -> String? 
      let mathFunction: (Double, Double) -> Double 
      let calculationDescription: (String, String) -> String 
      let firstOperand: (Double) 
      let descriptionOperand:(String) 
      func perform(with secondOperand:(Double)) -> Double { 
       return (mathFunction(firstOperand, secondOperand)) 
      } 
      func performDecription(with secondOperan:(String)) -> String { 
       return (calculationDescription(descriptionOperand, secondOperan)) 
      } 
     } 

     func setOperand(_ operand:Double) { 
      accumulator = (operand, String(Int(operand)), nil) 
     } 

     func setOperand(variable named: String) { 

      accumulator = (variables?[named] ?? 0, named, nil) 

     } 

     for item in memorySequence { 
      switch item { 
      case .operand(let operand): 

       setOperand(operand) 

      case .operation(let operation): 

       performOperation(operation) 

      case .variable(let variable): 

       setOperand(variable:variable) 
      } 
     } 


     if pendingBinaryOperation != nil { 

      return (accumulator!.digit, true, pendingBinaryOperation!.calculationDescription(pendingBinaryOperation!.descriptionOperand, accumulator!.description ?? ""), accumulator?.errorMessage) 

     } else { 

      return (accumulator!.digit, false, accumulator!.description ?? "", accumulator?.errorMessage) 

     } 

    } // end of evaluate with errors 
} 

回答

0

一個簡單的拼寫錯誤。在evaluateWithErrorReport中,你的返回值有一個「Double?」作爲顯示變量的類型包括「雙」而不是「雙?」。

+0

我試過了,仍然得到了同樣的錯誤。看來errorMessage是問題發生的地方。 –

+0

我通過將兩個display.result和accumulator.digit更改爲可選項來修復它。修復了導致代碼編譯沒有錯誤的所有語法錯誤之後。 –

相關問題