SwiftUIで行こう! 電卓を作ろ!-機能を追加!-仕上げ。
続いて、コードを整理していき、機能を追加していきます。
参考サイトです。
https://www.youtube.com/watch?v=hBO81LgQcJM
switch 文をも変更していきます。
switch symbol
を配列で置き換えます。symbolを"enum"でOperationとしてその種類を指定した算術式を定義します。
private enum Operation{
case constant(Double)
case unaryOperation((Double) -> Double)
case binaryOperation((Double,Double)->Double)
case equals
}
ここで、配列、辞書を作っていきます。
private var operations:Dictionary = [
"π" : Operation.constant(Double.pi),
"√" : Operation.unaryOperation(sqrt),
"X" : Operation.binaryOperation({$0 * $1}),
"=": Operation.equals
]
次からは、実際に演算子を受け取って表示部分に表示させるコードを書いていきます。ここではswich文を使います。
switch operation {
}
として、配列である変数"operation"の値により振り分けます。switch文全体のコードです。
mutating func performOperation(_ symbol:String){
if let operation = operations[symbol]{
switch operation {
case .constant(let value):
accumulator = value
case .unaryOperation(let function):
if accumulator != 0{
accumulator = function(accumulator!)
}
break
case .binaryOperation(let function):
if accumulator != nil {
pbo = PendingBinaryOperation(function: function, firstOperand: accumulator!)
accumulator = nil
}
case .equals:
performPendingBinaryOperation()
}
}
}
上2つの"case" の場合は、配列の中身は
"π" : Operation.constant(Double.pi),
"√" : Operation.unaryOperation(sqrt),
であり、
case .constant(let value):
accumulator = value
case .unaryOperation(let function):
if accumulator != 0{
accumulator = function(accumulator!)
}
break
このマークが押されたら即演算となりますので単純です。
次のswitch文、下2つの"case"は2つの数字を使った計算をするためのコードです。
case .binaryOperation(let function):
if accumulator != nil {
pbo = PendingBinaryOperation(function: function, firstOperand: accumulator!)
accumulator = nil
}
case .equals:
performPendingBinaryOperation()
その仕組みはというと以下2つの関数と1つの変数からなっています。
以下、"case .equals:"ということで"="を押した時の命令です。
private mutating func performPendingBinaryOperation() {
if pbo != nil && accumulator != nil {
accumulator = pbo!.perform(with: accumulator!)
pbo = nil
}
}
private var pbo: PendingBinaryOperation?
private struct PendingBinaryOperation {
let function: (Double, Double) -> Double
let firstOperand: Double
func perform(with secondOperand: Double) -> Double {
return function(firstOperand, secondOperand)
}
}
変数pboはstruct PendingBinaryOperation{}を実体化したもの、今回は掛け算を実行するコードです。
enum Operationの
case binaryOperation((Double,Double)->Double)
var operations:Dictionary
"X" : Operation.binaryOperation({$0 * $1}),
に該当します。
PendingBinaryOperation{}のfunc perform()で実際に2つの値について計算しています。
func perform(with secondOperand: Double) -> Double {
return function(firstOperand, secondOperand)
}
function(firstOperand, secondOperand)がvar operations:Dictionaryの
"X" : Operation.binaryOperation({$0 * $1}),
{$0 * $1}で計算されています。
struct CalcBrain{}の全体のコードです。
private enum Operation{
case constant(Double)
case unaryOperation((Double) -> Double)
case binaryOperation((Double,Double)->Double)
case equals
}
private var operations:Dictionary = [
"π" : Operation.constant(Double.pi),
"√" : Operation.unaryOperation(sqrt),
"X" : Operation.binaryOperation({$0 * $1}),
"=": Operation.equals
]
mutating func performOperation(_ symbol:String){
if let operation = operations[symbol]{
switch operation {
case .constant(let value):
accumulator = value
case .unaryOperation(let function):
if accumulator != 0{
accumulator = function(accumulator!)
}
break
case .binaryOperation(let function):
if accumulator != nil {
pbo = PendingBinaryOperation(function: function, firstOperand: accumulator!)
accumulator = nil
}
case .equals:
performPendingBinaryOperation()
}
}
}
private mutating func performPendingBinaryOperation() {
if pbo != nil && accumulator != nil {
accumulator = pbo!.perform(with: accumulator!)
pbo = nil
}
}
private var pbo: PendingBinaryOperation?
private struct PendingBinaryOperation {
let function: (Double, Double) -> Double
let firstOperand: Double
func perform(with secondOperand: Double) -> Double {
return function(firstOperand, secondOperand)
}
}
この記事が気に入ったらサポートをしてみませんか?