์๋ฌ ์ฒ๋ฆฌ๋ ํ๋ก๊ทธ๋๋ฐ์์ ๋นผ๋์ ์ ์๋ค. ์๋ฌ ๊ด๋ฆฌ๋ฅผ ์ ๋๋ก ํด๋์ด์ผ ์ถํ ๋๋ฒ๊น ์ ์์ด ์ด๋์ ๋ณผ ์ ์๋ค. ๋ฏธ๋์ ๋๋ฅผ ์ํ ํฌ์?์ ๊ฐ๋ ์ด๋ค. ์๋ฌ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ๋ ์ค์ํ์ง๋ง ์๋ฌ๋ฅผ ๋ด๋ ๋ฐฉ๋ฒ, ์๋ฌ๋ฅผ ๊ฐ์งํ์ฌ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์๋ ๊ฒ ์ญ์ ์ค์ํ๋ค. ์ค๋์ ์ด๋ฌํ ์๋ฌ์ ๋ํด ์์๋ณด๊ณ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด์.
ํํ
enum VendingMachineError: Error {
case invalidInput
case insuffcientFunds(moneyNeeded: Int)
case outOfStock
}
- ์ํ๊ธฐ์ ๋์ ์ค๋ฅ๋ฅผ ํํํ๋ค.
class VendingMachine {
let itemPrice: Int = 100
var itemCount: Int = 5
var deposited: Int = 0
// ๋์ ๋ฐ๋ ๋ฉ์๋
func receiveMoney(_ money: Int) throws {
guard money <= 0 else {
throw VendingMachineError.invalidInput
}
self.deposited += money
print("\(money)์ ๋ฐ์")
}
// ๋ฌผ๊ฑด์ ํ๋ ๋ฉ์๋
func vend(numberOfItems numberOfItemsToVend: Int) throws -> String {
// ์ํ๋ ์์ดํ
์ ์๋์ด ์๋ชป ์
๋ ฅ๋์์ผ๋ฉด ์ค๋ฅ๋ฅผ ๋์ง๋ค.
guard numberOfItemsToVend > 0 else {
throw VendingMachineError.invalidInput
}
// ํ์ฌ๊น์ง ๋ฃ์ ๋์ด ๊ตฌ๋งคํ๋ ค๋ ๋ฌผ๊ฑด์ ๊ฐ์ ๋๋น ๊ธ์ก์ ๋นํด ์ ์ผ๋ฉด ์๋ฌ๋ฅผ ๋ธ๋ค.
guard numberOfItemsToVend * itemPrice <= deposited else {
let moneyNeeded: Int
moneyNeeded = numberOfItemsToVend * itemPrice - deposited
throw VendingMachineError.insuffcientFunds(moneyNeeded: moneyNeeded)
}
// ๊ตฌ๋งคํ๋ ค๋ ์๋๋ณด๋ค ๋น์น๋์ด ์๋ ์์ดํ
์ด ์ ์ผ๋ฉด ์๋ฌ๋ฅผ ๋ธ๋ค.
guard itemCount >= numberOfItemsToVend else {
throw VendingMachineError.outOfStock
}
// ์ค๋ฅ๊ฐ ์์ผ๋ฉด ์ ์์ฒ๋ฆฌ๋ฅผ ํ๋ค.
let totalPrice = numberOfItemsToVend * itemPrice
self.deposited -= totalPrice
self.itemCount -= numberOfItemsToVend
return "\(numberOfItemsToVend)๊ฐ ์ ๊ณตํจ"
}
}
- ์ค๋ฅ๋ฅผ ๋์ง ๊ฐ๋ฅ์ฑ์ด ์๋ ๋ฉ์๋์ ๊ฒฝ์ฐ
throws
๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ฅ ๋ดํฌ ํจ์์์ ๋ํ๋ธ๋ค.
์ค๋ฅ ์ฒ๋ฆฌ
- ์ ๋ ๊ฒ ์์ฑํ ์ฝ๋์ ๋ํด ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง์ ๋ํ ์ฝ๋๋ ์์ฑํด์ผ ํ๋ค.
- ์ค๋ฅ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ฒ๋ฆฌ๋ฐฉ๋ฒ์ด๋ผ๋์ง, ๋ค๋ฅธ ์๋๋ฅผ ํ๋ค๋์ง, ์ฌ์ฉ์์๊ฒ ์ค๋ฅ๋ฅผ ์๋ฆฌ๊ณ ์ ํ์ ํ๋๋ก ํ๋ค๋์ง๋ฑ์ ์ฝ๋๋ฅผ ์์ฑํด์ผ ํจ
throws
๊ฐ ๋ฌ๋ ค์๋ ํจ์๋try
๋ฅผ ์ฌ์ฉํ์ฌ ํธ์ถํ๋ค.
do-catch
let machine: VendingMachine = VendingMachine()
do {
try machine.receiveMoney(0)
} catch VendingMachineError.invalidInput {
print("์
๋ ฅ์ด ์๋ชป๋์์ต๋๋ค.")
} catch VendingMachineError.insuffcientFunds(let moneyNeeded) {
print("\(moneyNeeded)์์ด ๋ถ์กฑํฉ๋๋ค.")
} catch VendingMachineError.outOfStock {
print("์๋์ด ๋ถ์กฑํฉ๋๋ค.")
} // ์
๋ ฅ์ด ์๋ชป๋์์ต๋๋ค.
- ๊ฐ์ฅ ์ ์์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก ๋ชจ๋ ์ค๋ฅ ์ผ์ด์ค์ ๋์๋๋ค.
// catch๋ฅผ ๊ณ์ํด์ ์ฐ๋ ๊ฒ์ด ๊ท์ฐฎ๋ค๋ฉด
do {
try machine.receiveMoney(300)
} catch /* (let error) */ { // ๋์ด์ค๋ ์๋ฌ์ ์ด๋ฆ์ ๋ฐ๊ฟ์ค ์ ์๋ค. ๊ธฐ๋ณธ์ error
switch error {
case VendingMachineError.invalidInput:
print("์
๋ ฅ์ด ์๋ชป๋์์ต๋๋ค.")
case VendingMachineError.insuffcientFunds(let moneyNeeded):
print("\(moneyNeeded)์์ด ๋ถ์กฑํฉ๋๋ค.")
case VendingMachineError.outOfStock:
print("์๋์ด ๋ถ์กฑํฉ๋๋ค.")
default:
print("์์ ์๋ ์ค๋ฅ \(error)")
}
} // 300์ ๋ฐ์
- catch๋ฅผ ๊ณ์ํด์ ์ฐ๋ ๊ฒ์ด ๊ท์ฐฎ๋ค๋ฉด ์ด๋ ๊ฒ๋ ํ ์ ์๋ค.
// ๊ตณ์ด ์๋ฌ๋ฅผ ๋ฐ๋ก ์ฒ๋ฆฌํ ํ์๊ฐ ์๋ค๋ฉด
var result: String?
do {
result = try machine.vend(numberOfItems: 4)
} catch {
print(error)
}
- ์๋ฌ๋ฅผ ๊ฐ๋ณ๋ก ์ฒ๋ฆฌํ ํ์๊ฐ ์๋ค๋ฉด ์ด์ ๊ฐ์ด ์จ๋ ๋ฌด๋ฐฉํ๋ค.
try?
- ๋ณ๋์ ์ค๋ฅ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ํต๋ณด๋ฐ์ง ์๊ณ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ ๊ฒฝ์ฐ ๊ฒฐ๊ณผ๊ฐ์ nil๋ก ๋ฐ์ ์ ์๋ค.
- ์ฆ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด nil, ๋ฐ์ํ์ง ์์ผ๋ฉด ์ต์ ๋ ํ์ ์ผ๋ก ๋ฆฌํด
let machine: VendingMachine = VendingMachine()
var result: String?
result = try? machine.vend(numberOfItems: 2)
result // Optional("2๊ฐ ์ ๊ณตํจ")
result = try? machine.vend(numberOfItems: 2)
result // nil
try!
- ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์ ๊ฒ์ด๋ผ๋ ํ์ ์ ๊ฐ์ง ๋ ์ฌ์ฉ
- ๋ฐ๋ก ๊ฐ์ ๋ฆฌํด ๋ฐ์ ์ ์์ง๋ง
- ๋ฐํ์ ์ค๋ฅ๊ฐ ๋ฐ์
result = try! machine.vend(numberOfItems: 1)
result // 1๊ฐ ์ ๊ณตํจ
//result = try! machine.vend(numberOfItems: 1)
// ๋ฐํ์ ์ค๋ฅ ๋ฐ์!
defer
- Clean up Action
- ํน์ code block์ ๋ฒ์ด๋ ๊ฒฝ์ฐ ๋ฐ๋์ ๋ถ๋ฆฌ๊ฒ ํ ์ ์์
- error๊ฐ ๋ฐ์ํ๋ฉด, code ์คํ ์์น๊ฐ jump ํด์ block์ ๋น ์ ธ๋๊ฐ๊ฒ ๋๋๋ฐ, ์ด ๋, ๋ฐ๋์ ์ฒ๋ฆฌํด์ผํ code๋ฅผ ์คํํ๊ฒ ํ ์ ์์