λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
⌨️ Language/swift

[Swift] μ—λŸ¬ 처리

by hyebin (Helia) 2024. 3. 28.
λ°˜μ‘ν˜•

μ—λŸ¬μ˜ ν‘œμ‹œμ™€ λ°œμƒ

enum VendingMachineError: Error {
     case invalidSelection
     case insufficientFunds(coinsNeeded: Int)
     case outOfStock
}

throw VendingMachineError.insufficientFunds(coinsNeeded: 5)

 

μ—λŸ¬ 처리

  1. μ—λŸ¬κ°€ λ°œμƒν•œ ν•¨μˆ˜μ—μ„œ λ¦¬ν„΄κ°’μœΌλ‘œ μ—λŸ¬λ₯Ό λ°˜ν™˜ν•΄ ν•΄λ‹Ή ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œ μ½”λ“œμ—μ„œ μ—λŸ¬λ₯Ό μ²˜λ¦¬ν•˜λ„λ‘ ν•˜λŠ” 방법
  2. do-catch ꡬ문을 μ‚¬μš©ν•˜λŠ” 방법
  3. μ˜΅μ…”λ„ 값을 λ°˜ν™˜ν•˜λŠ” 방법
  4. assertλ₯Ό μ‚¬μš©ν•΄ κ°•μ œλ‘œ ν¬λž˜μ‰¬λ₯Ό λ°œμƒμ‹œν‚€λŠ” 방법

μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚€λŠ” ν•¨μˆ˜ μ‚¬μš©ν•˜κΈ°

μ–΄λ–€ ν•¨μˆ˜, λ©”μ†Œλ“œ ν˜Ήμ€ μƒμ„±μžκ°€ μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚¬ 수 μžˆλ‹€λŠ” 것을 μ•Œλ¦¬κΈ° μœ„ν•΄ throw ν‚€μ›Œλ“œλ₯Ό ν•¨μˆ˜ μ„ μ–ΈλΆ€μ˜ νŒŒλΌλ―Έν„° 뒀에 뢙일 수 있음

func canThrowErrors() throws -> String

func cannotThrowErrors() -> String
struct Item {
    var price: Int
    var count: Int
}

class VendingMachine {
    var inventory = [
        "Candy Bar": Item(price: 12, count: 7),
        "Chips": Item(price: 10, count: 4),
        "Pretzels": Item(price: 7, count: 11)
    ]
    var coinsDeposited = 0

    func vend(itemNamed name: String) throws {
        guard let item = inventory[name] else {
            throw VendingMachineError.invalidSelection
        }

        guard item.count > 0 else {
            throw VendingMachineError.outOfStock
        }

        guard item.price <= coinsDeposited else {
            throw VendingMachineError.insufficientFunds(coinsNeeded: item.price - coinsDeposited)
        }

        coinsDeposited -= item.price

        var newItem = item
        newItem.count -= 1
        inventory[name] = newItem

        print("Dispensing \\(name)")
    }
}

let favoriteSnacks = [
    "Alice": "Chips",
    "Bob": "Licorice",
    "Eve": "Pretzels",
]

func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
     let snackName = favoriteSnacks[person] ?? "Candy Bar"
     try vendingMachine.vend(itemNamed: snackName)
}

struct PurchasedSnack {
    let name: String
    init(name: String, vendingMachine: VendingMachine) throws {
        try vendingMachine.vend(itemNamed: name)
        self.name = name
    }
}

 

do-catchλ₯Ό μ΄μš©ν•΄ μ—λŸ¬λ₯Ό μ²˜λ¦¬ν•˜κΈ°

do {
    try expression
    statements
} catch pattern 1 {
    statements
} catch pattern 2 where condition {
    statements
} catch {
    statements
}

var vendingMachine = VendingMachine()
vendingMachine.coinsDeposited = 8

do {
    try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)
    print("Success! Yum.")
} catch VendingMachineError.invalidSelection {
    print("Invalid Selection.")
} catch VendingMachineError.outOfStock {
    print("Out of Stock.")
} catch VendingMachineError.insufficientFunds(let coinsNeeded) {
    print("Insufficient funds. Please insert an additional \\(coinsNeeded) coins.")
} catch {
    print("Unexpected error: \\(error).")
}
// Prints "Insufficient funds. Please insert an additional 2 coins."

func nourish(with item: String) throws {
    do {
        try vendingMachine.vend(itemNamed: item)
    } catch is VendingMachineError {    
        // λͺ¨λ“  VendingMachineError ꡬ뢄을 μœ„ν•΄ isλ₯Ό μ‚¬μš©
        print("Invalid selection, out of stock, or not enough money.")
    }
}

do {
    try nourish(with: "Beet-Flavored Chips")
} catch {
    print("Unexpected non-vending-machine-related error: \\(error)")
      // μ—¬κΈ°μ—μ„œ 처럼 catchλ₯Ό κ·Έλƒ₯ if-elseμ—μ„œ else 같이 μ‚¬μš© κ°€λŠ₯
}
// Prints "Invalid selection, out of stock, or not enough money."

 

μ—λŸ¬λ₯Ό μ˜΅μ…”λ„ κ°’μœΌλ‘œ λ³€ν™˜ν•˜κΈ°

func someThrowingFunction() throws -> Int {
    // ...
}

let x = try? someThrowingFunction()
let y: Int?

do {
    y = try someThrowingFunction()
} catch {
    y = nil
}

func fetchData() -> Data? {
    if let data = try? fetchDataFromDisk() { return data }
    if let data = try? fetchDataFromServer() { return data }
    return nil
}

 

μ—λŸ¬ λ°œμƒμ„ μ€‘μ§€ν•˜κΈ°

  • ν•¨μˆ˜λ‚˜ λ©”μ†Œλ“œμ—μ„œ μ—λŸ¬κ°€ λ°œμƒλ˜μ§€ μ•Šμ„ 것이라고 ν™•μ‹ ν•˜λŠ” 경우 try!λ₯Ό μ‚¬μš©ν•  수 있음
  • let photo = try! loadImage(atPath: "./Resources/John Appleseed.jpg")

 

정리 μ•‘μ…˜ 기술

  • defer ꡬ문을 μ΄μš©ν•΄ ν•¨μˆ˜κ°€ μ’…λ£Œ 된 ν›„ 파일 μŠ€νŠΈλ¦Όμ„ λ‹«κ±°λ‚˜, μ‚¬μš©ν–ˆλ˜ μžμ›μ„ ν•΄μ§€ ν•˜λŠ” λ“±μ˜ 일을 ν•  수 있음
  • deferκ°€ μ—¬λŸ¬κ°œκ°€ μžˆλŠ” 경우 κ°€μž₯ λ§ˆμ§€λ§‰ 쀄뢀터 μ‹€ν–‰ λ©λ‹ˆλ‹€. 즉 bottom-up 순으둜 μ‹€ν–‰
func processFile(filename: String) throws {
    if exists(filename) {
        let file = open(filename)
        defer {
            close(file) // block이 λλ‚˜κΈ° 직전에 μ‹€ν–‰, 주둜 μžμ› ν•΄μ œλ‚˜ 정지에 μ‚¬μš©
        }
        while let line = try file.readline() {
            // Work with the file.
        }
        // close(file) is called here, at the end of the scope.
    }
}
λ°˜μ‘ν˜•

'⌨️ Language > swift' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[Swift] μ œλ„€λ¦­  (0) 2024.04.02
[Swift] ν”„λ‘œν† μ½œ  (0) 2024.03.29
[Swift] μ˜΅μ…”λ„ 체이닝  (0) 2024.03.26
[Swift] μ΄ˆκΈ°ν™”  (1) 2024.03.25
[Swift] 상속  (0) 2024.03.22