[iOS / Swift] Storyboard 간단한 계산기 만들기(2) 코드개선
옵셔널을 적용해서 코드를 개선해보겠음.
let a = Int(firstOperandField.text!)! // 이 코드를 안전하게 옵셔널 바인딩으로 바꾼 코드가 아래 코드
if let text = firstOperandField.text, let a = Int(text) {
}
아래처럼 하면 컴파일 에러가 발생하는 이유는?
=> 맨위 `if let text =` 안에 `let a`와 `let b`, 그리고 개별의 `let op`가 있는데 아래 `if op`, `a`, `b`가 위의 `if`문 안에 있어야 하는데 있지 않아서 찾을 수 없다는 컴파일 에러가 발생하는 것임.
오류 해결
=> 맨위 `if let text = firstOperandField.text, let a = Int(text)`코드블럭 안에 아래의 코드들을 담으면 됨
if let text = firstOperandField.text, let a = Int(text) {
if let text = secondOperandField.text, let b = Int(text) {
if let op = operatorButton.title(for: .normal) {
if op == "+" {
let result = a + b
resultLabel.text = "\(result)" // String Interpolation
} else if op == "-" {
let result = a - b
resultLabel.text = "\(result)"
} else if op == "*" {
let result = a * b
resultLabel.text = "\(result)"
} else if op == "/" {
let result = a / b
resultLabel.text = "\(result)"
} else {
print("연산자를 선택해주세요")
}
}
}
}
}
if let text = firstOperandField.text, let a = Int(text),
let text = secondOperandField.text, let b = Int(text), ㅋlet op = operatorButton.title(for: .normal) {
if op == "+" {
let result = a + b
resultLabel.text = "\(result)" // String Interpolation
} else if op == "-" {
let result = a - b
resultLabel.text = "\(result)"
} else if op == "*" {
let result = a * b
resultLabel.text = "\(result)"
} else if op == "/" {
let result = a / b
resultLabel.text = "\(result)"
} else {
print("연산자를 선택해주세요")
}
}
}
이 코드로도 사용 가능
이렇게 하면 오류가 사라짐. 아래 주석과 같은 맥락임.
// 왜 아래 두 if문은 text라는 이름을 두번 사용해도 컴파일 에러가 발생하지 않을까?
// => if let 에서 바인딩한 상수는 접근 범위가 해당 if블록으로 제한됨.
// if문이 끝나면 if문에 사용된 text가 사라지기 때문에 같은 이름을 사용해도 문제가 없음.
위에서는 `if let`에서 바인딩한 상수는 범위가 해당 if블럭에서 끝나기 때문에 if문이 끝나면 그 if문에서 사용된 상수가 사라지기 때문에 아래의 코드들에 나왔던 `op`를 비롯한 `a`, `b`를 받을 수 없게 되는 것이었음.
그러면 이렇게 코드를 강제 언래핑이 아닌 옵셔널 바인딩으로 수정하면 뭐가 좋음?
- 값이 nil일경우 앱에서 crash가 발생하여 시뮬레이터가 강제종료 됨
- 가독성이 올라가고 유지보수가 용이해짐
- 값이 nil인 경우와 값이 있는 경우를 명확히 구분하여 처리할 수 있음
`guard`문을 사용하면 가독성이 좋아짐
guard let text = firstOperandField.text, let a = Int(text) else {
return
}
guard let text = secondOperandField.text, let b = Int(text) else {
return
}
guard let op = operatorButton.title(for: .normal) else {
return
}
if op == "+" {
let result = a + b
resultLabel.text = "\(result)" // String Interpolation
} else if op == "-" {
let result = a - b
resultLabel.text = "\(result)"
} else if op == "*" {
let result = a * b
resultLabel.text = "\(result)"
} else if op == "/" {
let result = a / b
resultLabel.text = "\(result)"
} else {
print("연산자를 선택해주세요")
}
}
`guard` 문으로 바꾼다고 항상 가독성이 좋아지는 것은 아님!
추가로 아래 `if op == "+"` 부분의 코드를 `switch`문으로 변경해보겠음
var result: Int? = nil
switch op {
case "+" :
result = a + b
case "-" :
result = a - b
case "*" :
result = a * b
case "/" :
result = a / b
default :
break
}
guard let result else { return }
resultLabel.text = "\(result)"
}
먼저 `result`라는 변수를 `Int`옵셔널로 선언해주고 첫 값은 `nil`로 설정
그 다음 `switch`문을 사용해서 각각의 연산자를 `case`로 정해주고 그외는 `default`로 설정함
그다음 `guard let`으로 `result`를 바인딩함. 바인딩 할 수 없다면 `return`해서 끝냄
`result`에 값이 있다면 `resultLabel.text = "\(result)"`로 `result`값을 출력함
이렇게 코드개선을 한번 해봤는데 다음에는 값이 입력되지 않았을 때 경고를 띄우는걸 추가해보겠음
'Swift Study > Storyboard' 카테고리의 다른 글
[iOS / Swift] Storyboard 간단한 로그인 기능 구현(2) 코드 개선 (0) | 2025.01.13 |
---|---|
[iOS / Swift] Storyboard 간단한 계산기 만들기(3) 코드개선 (0) | 2025.01.06 |
[iOS / Swift] Storyboard 간단한 로또앱 만들기 (0) | 2024.12.11 |
[iOS / Swift] Storyboard 간단한 날씨앱 만들기 (1) | 2024.12.11 |
[iOS / Swift] Storyboard 간단한 로그인 기능 구현 (0) | 2024.12.09 |