//
// ViewController.swift
// calculator
//
// Created by 郭百度 on 2017/9/23.
// Copyright ? 2017年 Luke. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var display: UILabel!
var userIsInTheMiddleOfTyping = false
var lessOnePoint = true
@IBAction func touchDigit(_ sender: UIButton) {
let digit = sender.currentTitle!
//課后修正計算器bug添加,當(dāng)輸入為"."時判斷,屏幕上數(shù)字是否已有小數(shù)點,是的話不執(zhí)行
let point: Character = "."
if digit == String(point) && display.text!.contains(".") {
lessOnePoint = false
}
if lessOnePoint {
if userIsInTheMiddleOfTyping {
let textCurrentlyInDisplay = display.text!
display.text = textCurrentlyInDisplay + digit
print("I'm \(digit) b")
} else {
display.text = digit
userIsInTheMiddleOfTyping = true
print("I'm \(digit) c")
}
}
lessOnePoint = true
}
var displayVaule: Double {
get {
return Double(display.text!)!
}
set {
display.text = String(newValue)
}
}
private var brain = CalculatorBrain()
@IBAction func performOperation(_ sender: UIButton) {
//執(zhí)行運算按鈕中,如果用戶正在鍵入中,那么將display值提交到brain的蓄存器中,用于實現(xiàn)當(dāng)用戶點擊開根號等計算時,將屏幕display數(shù)進行緩存
if userIsInTheMiddleOfTyping {
brain.setOperand(displayVaule)
}
//標(biāo)識用戶停止鍵入
userIsInTheMiddleOfTyping = false
//那么讓model執(zhí)行數(shù)學(xué)運算符判斷,將輸入值sender標(biāo)題→mathmaticalSymbol數(shù)學(xué)符號→brain執(zhí)行運算函數(shù)
if let mathmaticalSymbol = sender.currentTitle {
brain.performOperation(mathmaticalSymbol)
}
//那么讓我們將model中的結(jié)果從堆中復(fù)制給view中result,在view中將其復(fù)制給屏幕(label)
if let result = brain.result {
displayVaule = result
}
}
}
//
// CalculatorBrain.swift
// calculator
//
// Created by 郭百度 on 2017/9/23.
// Copyright ? 2017年 Luke. All rights reserved.
//
import Foundation
//func changeSign(operand: Double) -> Double {
// return -operand
//}
//func multiply(op1:Double, op2:Double) -> Double{
// return op1 * op2
//}
struct CalculatorBrain {
//構(gòu)建私有變量accumulator雙精度蓄存器
private var accumulator: Double?
private enum Operation {
case constant(Double)
case unaryOperation((Double) -> Double)
case binaryOperation((Double,Double) -> Double)
case equals
}
//生命私有變量operations(加了s)為字典,為字典賦值
private var operations: Dictionary<String,Operation> = [
"π" : Operation.constant(Double.pi),
"e" : Operation.constant(M_E),//M_E,
"√" : Operation.unaryOperation(sqrt),//sqrt,
"cos" : Operation.unaryOperation(cos), //cos
"±" : Operation.unaryOperation({-$0}), //±
"+" : Operation.binaryOperation({ $0 + $1} ), // x *
"-" : Operation.binaryOperation({ $0 - $1 }), // x *
"×" : Operation.binaryOperation({ $0 * $1 }), // x *
"÷" : Operation.binaryOperation({ $0 / $1 }), // x *
"=" : Operation.equals
]
//構(gòu)建多變函數(shù)執(zhí)行運算,輸入值忽略標(biāo)簽,變量symbol符號,類型為字符串
mutating func performOperation(_ symbol: String) {
//如果字典查詢operations[symbol]有值的話,將其賦值給變量operation,沒有則跳過整個枚舉
if let operation = operations[symbol] {
//對賦值后的operation進行解析
switch operation {
//聲明字典內(nèi)提取為“值”value,將字典內(nèi)常數(shù)值直接給蓄存器
case .constant(let value):
accumulator = value
//聲明字典內(nèi)提取為“函數(shù)”function,蓄存器中若不為nil,則進行sqrt、cos等枚舉的函數(shù)運算,否則跳過
case .unaryOperation(let function):
if accumulator != nil {
accumulator = function(accumulator!)
}
//聲明字典內(nèi)提取為“二元函數(shù)運算”同樣適用function(不同枚舉不沖突),蓄存器中若不為nil,則進行枚舉binaryOperation字典中的運算公式,運算函數(shù)為function,為區(qū)別,此處與官方教程不同使用了function2和functionVaule更易懂
case .binaryOperation(let functionVaule):
if accumulator != nil {
pendingBinaryOperation = PendingBinaryOperation(funciton2: functionVaule, firstOperand: accumulator!)
accumulator = nil
}
case .equals:
performPendingBinaryOperation()
}
} else {
//之前一個用x當(dāng)乘號一個用×當(dāng)乘號……然后乘法一直沒用……坑
print("沒有找到枚舉值")
}
}
private mutating func performPendingBinaryOperation() {
if pendingBinaryOperation != nil && accumulator != nil {
accumulator = pendingBinaryOperation!.perform(with: accumulator!)
pendingBinaryOperation = nil
}
}
private var pendingBinaryOperation: PendingBinaryOperation?
private struct PendingBinaryOperation {
//此處聲明了二元函數(shù)運算中為兩個雙精度變量輸入及一個雙精度變量輸出
let funciton2 : (Double,Double) -> Double
let firstOperand : Double
func perform(with secondOperand:Double) -> Double {
//此處調(diào)用了function為枚舉計算公式,在swift中使用$0、$1...按順序輸入變量
return funciton2(firstOperand,secondOperand)
}
}
mutating func setOperand(_ operand:Double) {
accumulator = operand
}
//輸出結(jié)果
var result: Double? {
get {
return accumulator
}
}
}
引用
Swift 語言 iOS10 開發(fā) 斯坦福(Stanford) CS193p 公開課(1)
Swift 語言 iOS10 開發(fā) 斯坦福(Stanford) CS193p 公開課(2)
Swift 語言 iOS10 開發(fā) 斯坦福(Stanford) CS193p 公開課(3)