首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >displays =brain.evaluateWithErrorReport(使用: dictionaryForVaribles)会显示错误,除非是as!已添加。为什么?

displays =brain.evaluateWithErrorReport(使用: dictionaryForVaribles)会显示错误,除非是as!已添加。为什么?
EN

Stack Overflow用户
提问于 2017-06-24 05:49:32
回答 1查看 41关注 0票数 1

视图文件中出现错误的行是:

代码语言:javascript
复制
 displays = brain.evaluateWithErrorReport(using: dictionaryForVaribles)

我收到的错误是:

代码语言:javascript
复制
/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。

查看文件:

代码语言:javascript
复制
//
//  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
//        } */
    }
}

模型文件:

代码语言:javascript
复制
//
//  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
}
EN

回答 1

Stack Overflow用户

发布于 2017-06-24 06:20:12

一个简单的打字错误。在evaluateWithErrorReport中,您的返回值有"Double?“其中,显示变量的类型包括"Double“而不是"Double?”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44730390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档