1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| import Foundation
//不要任何关于UI的内容,因为这里是model
class CalculatorBrain
{
//首先创建一个类型为op的数组,这个数组会在下面的enum op中定义,然后将其实例化为opstack
private var opStack = [Op]()
//枚举三种情况,这三种情况
private enum Op
{
case Operand(Double)//一个数
case UnaryOpertaion(String, Double -> Double)//一个运算符和一个数的运算(运算为一个函数,参数是double,类型也是double)
case BinaryOpertaion(String, (Double,Double) -> Double)//一个运算符和两个数的运算(运算为一个函数,参数是两个double,类型是double)
}
//创建一个字典,对应数值和运算方法。
private var knownOps = [String:Op]()
/*初始化时,先给好knownOps的值,分别为,
x:BinaryOpertaion,
÷:BinaryOpertaion,
+:BinaryOpertaion,
-:BinaryOpertaion,
√:UnaryOpertaion*/
init()
{
knownOps["×"] = Op.BinaryOpertaion("×", *)
knownOps["÷"] = Op.BinaryOpertaion("÷"){ $1 / $0 }
knownOps["+"] = Op.BinaryOpertaion("+", +)
knownOps["-"] = Op.BinaryOpertaion("-"){ $1 - $0 }
knownOps["√"] = Op.UnaryOpertaion("√"){ sqrt($0) }
}
let brain = CalculatorBrain()
func pushOperand(operand: Double ) -> Double? //输入一个数,没有运算
{
opStack.append(Op.Operand(operand))//如果这仅仅是一个数,那就作为Op.Operand类型传入
println(Op.Operand(operand))//类似于opstack[x]的这种感觉
return evaluate()
}
func evaluate() -> Double?{//为什么double要用optional?其实这个还不是很明白。
//这是evalaute的起始位置,上面的evaluate都是从这里开始的。
let(result, remainder) = evaluate(opStack)
return result
}
private func evaluate(ops: [Op]) -> (result: Double?, remainingOps: [Op])//输出的东西叫做tuple,算是一个好几个数据的小组合吧,类似于dictionary
{
if !ops.isEmpty{//如果ops不是空的
var remainingOps = ops //因为ops是作为参数传入的,传入之后默认的就是一个只读的变量,所以要再赋值给一个可变的变量
let op = remainingOps.removeLast()//这样就可以读取最后的那个元素了。那个原始还是一个op类型的东东。
switch op
{//下面我们来看看这这个元素是什么
case .Operand(let operand)://如果是一个数字,这个operand就是同时传过来的那个数,相当于enum中的Op.Operand(let operand)
return (operand, remainingOps)//输出一个数字和剩下的栈
case .UnaryOpertaion(_, let operation)://如果是一个一元操作符,情况会稍微复杂一些
let operandEvaluation = evaluate(remainingOps)//看来我们需要对operandEvaluation
if let operand = operandEvaluation.result{//那我们就去看下
return (operation(operand), operandEvaluation.remainingOps)
}
case .BinaryOpertaion(_, 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)//如果栈中什么都不剩了,那就返回一个nil,所以返回值
}
func performOperaction(symbol: String) ->Double?
{
if let operation = knownOps[symbol]//operation是一个optional op的类型,所以,这个赋值可以作为一个条件判断。当值为nil的时候,那if就是false,否则if的条件为true
{
opStack.append(operation)
}
return evaluate()
}
} |