Swift Apple-计算器-Demo源码解读

【Demo 下载】

如图:



涉及到以下知识:
  • do {
    } catch let error {
    }
  • try throws guard
  • extension
  • contains
  • UIStackView
布局 - UIStackView




throws配合 do {
} catch let error {
}
使用
如:

do {
            throw CalculatorError.nilInput

        } catch let error{
            print("\(error.localizedDescription)")

        }

其中:

public enum CalculatorError: Error {
    case invalidCharater
    case multipleCharacters
    case nilInput
}

可以配合使用:

do {
            guard let input = input else {
                throw CalculatorError.nilInput
            }
        } catch let error{
            print("\(error.localizedDescription)")

        }

再深入一点

声明:

        func iInputChara(_ input: String?) throws {

        guard let input = input else {
            throw CalculatorError.nilInput
        }

    }

使用

override func viewDidLoad() {
        super.viewDidLoad()

        do {
           try iInputChara("d")
        } catch let error{
            print("\(error.localizedDescription)")

        }
    }

下面开始计算器代码:

open class Calculator {

}

open 该权限是最大的权限,允许访问文件,同时允许继承、重写

public init() {
        self.display = String()
        self.operatorValue = nil
    }

public 允许访问但不允许继承、重写

    fileprivate let period = "."
    fileprivate var display: String
    fileprivate var leftOperand: Double?
    fileprivate var operatorValue: String?
    fileprivate var isLastCharacterOperator = false

fileprivate设为私有属性
fileprivate 允许文件内访问
private 只允许当前对象的代码块内部访问

public var displayValue: String {
        get {
            return !(display.isEmpty) ? display : "0"
        }
    }

重写get方法,使得每次获取displayValue时都取决于!(display.isEmpty),这个很高明

public func input(_ input: String?) throws {

}

_ input: String?说明传参可为空

guard let input = input else {
            throw CalculatorError.nilInput
        }

判断参数为空时抛出错误

一个String的extension

extension String {

    /// Determines whether the string is the Delete charater.
    var isDelete: Bool {
        return (self == "D")
    }

    /// Determines whether the string is a period.
    var isPeriod: Bool {
        return (self == ".")
    }

    /// Determines whether the string is the Clear charater.
    var isClear: Bool {
        return (self == "C")
    }

    /// Determines whether the string is a period or a number between 0 and 9.
    var isValidDigit: Bool {
        let digits = "0123456789."
        return digits.contains(self)
    }

    /// Determines whether the string is an operator such as +, -, *, or /.
    var isOperator: Bool {
        let operators = "+-*/"
        return operators.contains(self)
    }

    /// Determines whether the string is an equal sign.
    var isEqualSign: Bool {
        return (self == "=")
    }

    /// Determines whether a string is a valid character such as a digit, a.
    var isValidCharacter: Bool {
        return ( isValidDigit || isOperator || isDelete || isClear || isPeriod || isEqualSign)
    }
}

上文已经声明了一个枚举,下面扩展LocalizedError协议

public enum CalculatorError: Error {
    case invalidCharater
    case multipleCharacters
    case nilInput
}

extension CalculatorError: LocalizedError {

    public var errorDescription: String? {
        switch self {
            case .invalidCharater: return NSLocalizedString("Invalid character exception.", comment: "The input is not a number between 0-9, an operator (+, -, *, /), D, C, =, or a period.")
            case .multipleCharacters: return NSLocalizedString("Multiple characters exception.", comment: "The input contains more than one character.")
            case .nilInput: return NSLocalizedString("Nil exception.", comment: "The input is nil.")
        }
    }
}

然后就是逻辑处理了


        // If the inputted character is a number (between 0 and 9) or a period, update the display.
        if input.isValidDigit {

            if isLastCharacterOperator {

                display = input
                isLastCharacterOperator = false
            }
            else if !input.isPeriod || !(display.contains(period)) {
                // Add it to the current display.
                display += input
            }
        }
        /*
             If the inputted character is an operator, save it in operatorValue and the current displayed value in leftOperand.
             If the inputted character is an equal sign, call the operation function to perform a calculation
             using leftOperand, the current displayed value, and operatorValue, then save the result in the display variable.
        */
        else if input.isOperator || input.isEqualSign {

            if (operatorValue == nil) && !(input.isEqualSign) {

                leftOperand = Double(displayValue)
                operatorValue = input
            }
            else {
                if let sign = operatorValue, let operand = leftOperand, let rightOperand = Double(displayValue) {

                    if let result = operation(left: operand, right: rightOperand, sign: sign) {
                        // Update the display with the operation's result.
                        display = "\(String(format: "%g", result))"
                    }
                }
                operatorValue = (input.isEqualSign) ? nil : input
            }

            isLastCharacterOperator = true
        }
        // if the inputted character is "C" and there is something displayed, clear it. Clear the saved operator, otherwise.
        else if input.isClear {
            if !(display.characters.isEmpty) {
                display.removeAll()
            }
            else {
                operatorValue = nil
            }
        }
        // If the inputted character is "D" and there is something displayed, remove its last character.
        else if input.isDelete {
            if !display.isEmpty {
                display = String(display.characters.dropLast())
            }
            isLastCharacterOperator = false
        }

可以看出,一个简单地计算器Demo写的如此精美,大家可以细细品味

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值