이 영역을 누르면 첫 페이지로 이동
Daily Growth 블로그의 첫 페이지로 이동

Daily Growth

페이지 맨 위로 올라가기

Daily Growth

Loving you is the reason I live. That’s why every day is precious, a step toward my dreams and you.

Swift 오류처리 : 자판기 예제로 배우는 throw, throws, try, do-catch, switch-case, defer

  • 2025.05.21 13:21
  • IT

Swift 오류 처리

🧯 Swift 오류 처리 

Swift에서 프로그래밍을 하다 보면 예상치 못한 문제가 생길 수 있다. 예를 들어 자판기를 만든다고 할 때, 사용자가 잘못된 금액을 넣거나 제품이 부족한 상황 등이 오류가 될 수 있다. 이런 문제들을 깔끔하게 처리하는 것이 바로 오류 처리(Error Handling)이고, Swift는 이를 위한 다양한 기능을 제공한다. 오늘은 그 개념들을 정말 쉽게, 단계별로 정리해보았다(:

 

1. 오류는 어떻게 표현할까?

Swift에서는 Error라는 빈 프로토콜을 통해 오류를 정의한다. 보통은 enum을 사용해서 오류의 종류를 나눈다. 열거형은 다양한 오류 상태를 구분하기에 적합한 구조다.

enum VendingMachineError: Error {
    case invalidInput
    case insufficientFunds(moneyNeeded: Int)
    case outOfStock
}

각 case는 자판기에서 발생할 수 있는 오류 상황이다. 예를 들어 돈을 잘못 넣었을 때는 invalidInput, 돈이 부족하면 insufficientFunds, 재고가 없으면 outOfStock이다.

 

2. 오류를 던지기: throw

throw는 "지금 문제가 생겼어요!" 하고 Swift에게 알려주는 신호다. 오류를 던질 때는 위에서 만든 enum case를 사용한다.

throw VendingMachineError.invalidInput

하지만 throw는 아무 함수에서나 쓸 수 없다. 이 오류를 던지려면 해당 함수가 오류를 던질 수 있다고 미리 선언해야 한다. 그 선언이 바로 throws다.

 

3. 오류를 던질 수 있게 하기: throws

throws는 함수 선언부에 붙는다. 이 함수 안에서는 오류를 던질 수 있다는 걸 알려주는 역할을 한다.

func receiveMoney(_ money: Int) throws {
    guard money > 0 else {
        throw VendingMachineError.invalidInput
    }
}

여기서 throw는 오류를 실제로 발생시키는 실행 구문이고, throws는 이 함수가 그런 행동을 할 수 있다는 약속이다.

정리하면:

  • throws는 throw를 쓸 수 있는 울타리
  • throw는 실제로 오류를 던지는 실행

 

4. 자판기 예제로 익히는 전체 흐름

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
        }
        deposited += money
        print("\(money)원 받음")
    }

    func vend(numberOfItems: Int) throws -> String {
        guard numberOfItems > 0 else {
            throw VendingMachineError.invalidInput
        }
        guard numberOfItems * itemPrice <= deposited else {
            throw VendingMachineError.insufficientFunds(
                moneyNeeded: numberOfItems * itemPrice - deposited
            )
        }
        guard itemCount >= numberOfItems else {
            throw VendingMachineError.outOfStock
        }

        deposited -= numberOfItems * itemPrice
        itemCount -= numberOfItems

        return "\(numberOfItems)개 제공함"
    }
}

 

5. 오류를 처리하는 방법: do-try-catch

throws 함수는 호출할 때 try를 붙여야 한다. 그리고 오류가 날 수 있기 때문에 do-catch 블록으로 감싸서 대응해야 한다.

do {
    try machine.receiveMoney(0)
} catch VendingMachineError.invalidInput {
    print("입력이 잘못되었습니다")
} catch VendingMachineError.insufficientFunds(let moneyNeeded) {
    print("\(moneyNeeded)원이 부족합니다")
} catch VendingMachineError.outOfStock {
    print("수량이 부족합니다")
}

switch로 오류 분기 처리하기

위 코드처럼 catch 여러 개를 써도 되지만, 하나의 catch로 받아서 내부에서 switch로 나누는 방법도 있다.

do {
    try machine.receiveMoney(0)
} catch {
    switch error {
    case VendingMachineError.invalidInput:
        print("입력이 잘못되었습니다")
    case VendingMachineError.insufficientFunds(let moneyNeeded):
        print("\(moneyNeeded)원이 부족합니다")
    case VendingMachineError.outOfStock:
        print("수량이 부족합니다")
    default:
        print("알 수 없는 오류: \(error)")
    }
}

왜 switch로도 처리할까?

  • catch가 하나라서 코드가 덜 길다
  • 외부에서는 Error 타입으로 받고, 내부에서 세부 분류하기 때문에 유연하다
  • 때로는 enum 이외의 다양한 오류 타입을 묶어 처리할 수 있다

💡 switch-case는 꼭 enum일 때만 쓰는 건 아니다.
Swift의 switch는 어떤 값이든 조건에 따라 나눌 수 있게 해주는 분기문이다.
위 예시에서는 error 값이 어떤 오류인지 case로 나눠서 처리한 것이다.

 

6. try?, try! 도 있다

Swift는 편하게 쓰기 위한 try?, try! 도 제공한다.

try?

  • 오류가 발생하면 nil 반환
  • 성공하면 Optional 값 반환
let result = try? machine.vend(numberOfItems: 2)
print(result) // Optional("2개 제공함") 또는 nil

try!

  • "절대 오류 안 날 거야!"라는 확신이 있을 때 사용
  • 오류 나면 앱이 바로 죽는다 (크래시 발생)
let result = try! machine.vend(numberOfItems: 1)
print(result) // "1개 제공함"

 

 

7. 보너스 개념: defer

defer는 "지금 당장은 아니지만, 이 함수 끝나기 전에 무조건 실행해줘!" 라고 예약해두는 기능이다.

예를 들어 문을 열었다가 함수 끝나기 전에 반드시 닫아야 한다면 이렇게 쓸 수 있다:

func useResource() {
    print("문 열기")
    defer {
        print("문 닫기")
    }

    print("안에서 작업 중...")
}
// 출력 결과:
// 문 열기
// 안에서 작업 중...
// 문 닫기
  • defer는 주로 정리 작업, 파일 닫기, 리소스 해제 등에 사용된다
  • defer는 함수가 어떻게 종료되든 간에 무조건 실행된다는 특징이 있다

 

8. 핵심 정리 요약

enum + Error 오류 타입 정의
throw 실제 오류 발생 시 사용
throws 오류를 던질 수 있는 함수로 선언
try 오류 발생 가능한 함수 호출 시 사용
do-catch 오류를 분기해서 처리
switch-case 오류를 하나의 catch에서 나눠서 처리 가능
try? 오류 시 nil 반환
try! 오류 없다고 확신할 때 (주의!)
defer 함수 끝나기 전에 반드시 실행되는 코드 예약

 


throw, throws, try, do-catch의 관계를 이해하고, 자판기처럼 현실적인 예제로 연습해보자. switch-case, defer 등도 실무에서 자주 쓰이니 함께 알아두면 좋다. 🥰  무엇보다 중요한 것은 직접 여러 예제를 작성하며 손에 익히는 것!

반응형

'IT' 카테고리의 다른 글

Swift 핵심 개념 정리 : 제네릭, 프로토콜, ARC와 강한 순환 참조  (0) 2025.05.23
Swift 고차 함수 쉽게 배우기: map, filter, reduce 실전 예제  (0) 2025.05.22
Swift 익스텐션 활용법: 연산 프로퍼티, 메서드, 서브스크립트 추가하기  (0) 2025.05.14
스위프트 프로토콜 vs 클래스 상속: 유연한 기능 구현을 위한 최적의 선택  (0) 2025.05.11
Swift : assert, guard, 그리고 제어 흐름 제어문  (0) 2025.05.11

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • Swift 핵심 개념 정리 : 제네릭, 프로토콜, ARC와 강한 순환 참조

    Swift 핵심 개념 정리 : 제네릭, 프로토콜, ARC와 강한 순환 참조

    2025.05.23
  • Swift 고차 함수 쉽게 배우기: map, filter, reduce 실전 예제

    Swift 고차 함수 쉽게 배우기: map, filter, reduce 실전 예제

    2025.05.22
  • Swift 익스텐션 활용법: 연산 프로퍼티, 메서드, 서브스크립트 추가하기

    Swift 익스텐션 활용법: 연산 프로퍼티, 메서드, 서브스크립트 추가하기

    2025.05.14
  • 스위프트 프로토콜 vs 클래스 상속: 유연한 기능 구현을 위한 최적의 선택

    스위프트 프로토콜 vs 클래스 상속: 유연한 기능 구현을 위한 최적의 선택

    2025.05.11
다른 글 더 둘러보기

정보

Daily Growth 블로그의 첫 페이지로 이동

Daily Growth

  • Daily Growth의 첫 페이지로 이동

검색

메뉴

    카테고리

    • 분류 전체보기 (432) N
      • Design History (69)
      • IT (134) N
      • Typography (13)
      • UX • UI Design (10)
      • Money (62)
      • Health (53)
      • Words (6)
      • Reading (20)
      • English (64)

    나의 외부 링크

    • lody.design
    • lody.canada
    • lody.study
    • lody.diary

    정보

    self-improvement의 Daily Growth

    Daily Growth

    self-improvement

    블로그 구독하기

    • 구독하기
    • 네이버 이웃 맺기
    • RSS 피드

    방문자

    • 전체 방문자
    • 오늘
    • 어제

    티스토리

    • 티스토리 홈
    • 이 블로그 관리하기
    • 글쓰기
    Powered by Tistory / Kakao. Copyright © self-improvement.

    티스토리툴바