より良くするために考えたいのが、 これだと
case .division:
if secondValue != 0 {
value = firstValue / secondValue
}
と
if currentOperator == .division && secondValue == 0
で判定が二重になってしまうので、 これを回避するために、こんなふうにも書けます。
guard currentOperator == .division && secondValue != 0 else {
label.text = "ERROR"
firstValue = 0
secondValue = 0
currentOperator = .undefined
return
}
var value = 0
switch currentOperator {
case .addition:
value = firstValue + secondValue
case .subtraction:
value = firstValue - secondValue
case .multiplication:
value = firstValue * secondValue
case .division:
value = firstValue / secondValue
default:
value = firstValue
}
label.text = "\(value)"
firstValue = 0
secondValue = 0
currentOperator = .undefined
}
しかしこれでもまだ不十分。 gurad else
内部の処理と、一番下の処理をまとめたい。
なので、defer
文というのでまとめてみる。
@IBAction func equalButtonTapped(_ sender: UIButton) {
defer {
firstValue = 0
secondValue = 0
currentOperator = .undefined
}
guard currentOperator == .division && secondValue != 0 else {
label.text = "ERROR"
return
}
var value = 0
switch currentOperator {
case .addition:
value = firstValue + secondValue
case .subtraction:
value = firstValue - secondValue
case .multiplication:
value = firstValue * secondValue
case .division:
value = firstValue / secondValue
default:
value = firstValue
}
label.text = "\(value)"
}
defer
は、そのメソッドのスコープを抜けるときに一番最後に必ず呼ばれる処理ブロックを表す。(詳細Swift参照)
これによって、正常に処理が進んで、メソッドのスコープから抜けるときも、guardから抜けるときも、最後に共通の処理が行われる。