Swift 오류 처리

고라니·2023년 7월 7일
0

TIL

목록 보기
2/67

오류 처리란?

프로그램은 항상 우리가 원하는대로 작동한다는 보장이 없다. 특히 복잡한 데이터나 자원을 많이 소비하는 작업의 경우 오류 발생 확률이 높아진다. 이에 대비하여 개발자는 예상 가능한 오류들을 적절하게 처리할 수 있어야 한다.

Swift의 오류 처리

스위프트에서 오류는 Error 프로토콜을 준수하는 타입의 값으로 표현한다. Error프로토콜 자체에는 요구사항이 없지만, 오류를 표현하기 위한 타입(주로 enum)으로 Error 프로토콜을 채택한다.

Error프로토콜

열거형(enum)은 오류의 종류를 나타내기 아주 적합하다.
아래의 코드는 자동차 시동을 걸기 위한 함수가 던지는 에러의 종류를 표현한 CarIgnitionError 열거형이다.

enum CarIgnitionError: Error {
    case keyMissing // 키가 없음
    case noGasoline // 기름 없음
    case batteryDepleted // 배터리 방전
}

Error 프로토콜을 채택하여 오류처리를 위한 타입이라는 것을 알 수 있다.

throw와 throws

  • throw는 오류를 실제로 발생시키는 키워드다. throw 뒤에는 오류를 던질 Error 프로토콜을 채택한 타입의 인스턴스를 넣어준다.
  • throws는 함수나 메서드가 오류를 던질 수 있다는 것을 표현하는 키워드이다. 이 키워드는 함수의 선언부에 위치하며, 함수의 파라미터 목로과 반환 타입 사이에 위치한다.
  • 이렇게 선언한 함수나 메서드를 호출할 때는 try를 사용하여 호출해야 한다.
  • 만약 do-catch 블록을 사용해 오류를 처리하지 않으면, 이후의 코드는 중단된다.
var isKey: Bool = true
var gasoline: Int = 30
var battery: Int = 0

func carIgnition() throws {
    guard isKey else {
        throw CarIgnitionError.keyMissing
    }

    guard gasoline >= 10 else {
        throw CarIgnitionError.noGasoline
    }

    guard battery != 0 else {
        throw CarIgnitionError.batteryDepleted
    }

    print("시동이 걸렸습니다.")
}

battery가 0 이므로 batteryDeplated 오류를 던진다.

try와 do-catch

  • try 키워드는 오류를 던질 수 있는 함수나 메서드를 호출할 때 사용 되며, 오류가 발생하면 catch블록으로 넘어가 오류를 처리할 수 있다.
  • try 키워드를 do 블록 밖에서 사용하면 컴파일 오류가 발생한다.

try? 와 try!

try?와 try!를 사용하면 do-catch구문 없이 오류 처리를 간소화할 수 있다.

  • try?는 오류를 발생시킬 수 있는 코드를 호출하고, 오류가 발생하면 nil을 반환하며, 오류가 발생하지 않으면 결과를 옵셔널로 래핑하여 반환한다. 오류 발생을 무시하고 실행을 계속 하려는 경우 유용하다.
  • try!는 오류가 발행하면 프로그램을 종료시킨다. 따라서 오류가 절대 발생하지 않을 것이라는 확신이 있을 때만 사용한다.

오류 전파

스위프트에서는 오류를 발생시킨 코드에서 직접 오류를 처리하는 것이 아니라, 이를 호출한 코드로 오류를 '전파'하여 처리하는 방식도 지원한다. 이를 통해 오류 처리를 더 적절한 위치에서 진행할 수 있으며 함수나 메소드의 역할을 더욱 명확하게 하여 코드의 가독성과 유지 보수성을 높일 수 있다.

enum FileError: Error {
    case fileNotFound
}

func readFile(at path: String) throws -> String {
    // 파일을 읽어서 문자열을 반환하는 코드 위치
    // 만약 파일을 찾을 수 없다면, FileError.fileNotFound 오류 던짐
    throw FileError.fileNotFound
}

func printFileContents() {
    do {
        let contents = try readFile(at: "/some/path")
        print(contents)
    } catch {
        print("Failed to read file: \(error)")
    }
}

readFile(at:) 함수는 파일을 읽는 역할만 하며, 오류를 던지고 오류를 처리하는 곳은 오류를 호출한 printFileContents()함수다. 이런 식으로 각 함수나 메소드는 자신의 역할에 집중할 수 있고, 오류 처리를 더 적절한 위치에서 진행할 수 있다.

결론

Swift에서 오류 처리는 많은 문제들을 대처하도록 돕는다. 이는 Error프로토콜을 준수하는 오류 타입, throws 및 throw 키워드를 사용한 요류처리와 do-catch 및 try, try!, try? 키워드를 통한 오류 핸들링 등을 통해 이루어진다.

결국 오류 처리는 코드의 안정성을 향상시키고, 예상하지 못한 상황에 대비하며, 코드의 가독성과 유지 보수성을 높이는데 큰 역할을 한다.

profile
🍎 무럭무럭

0개의 댓글