러스트의 에러와 예외 처리 방법에 대해서 알아보겠습니다.
1. 러스트의 에러
러스트는 두가지 에러가 있습니다.
- 복구 가능한 에러(Recoverable Error)
- 복구 불가능한 에러(Unrecoverable Error)
복구 가능한 에러는 프로그램에서 문제가 발생한 것을 캐치하고 예외 처리를 할 수 있습니다.
반면에, 복구 불가능한 에러는 에러를 발생시키며 프로그램이 종료됩니다.
2. 복구 불가능한 에러(Unrecoverable Error)
복구 불가능한 에러는 에러 발생 즉시 프로그램이 종료되며, 개발자에게 문제가 발생했음을 알리며 디버깅 정보를 제공합니다.
panic!() 함수
panic!(msg)
을 사용하여 복구 불가능한 에러를 명시적으로 발생시킬 수 있습니다.
- 프로그램 동작 중, 예상하지 못한 동작을 할 때 panic 함수로 프로그램을 즉시 종료시킬 수 있음
fn main() {
panic!("Something wrong, crash");
}
위의 코드를 실행하면 에러가 발생하여 프로그램이 종료되면서 인자로 전달된 메시지와 콜스택이 함께 출력됩니다.
thread 'main' panicked at 'Something wrong, crash', src/main.rs:2:5
stack backtrace:
0: rust_begin_unwind
at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library/std/src/panicking.rs:579:5
1: core::panicking::panic_fmt
at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library/core/src/panicking.rs:64:14
2: RustExample::main
at ./src/main.rs:2:5
3: core::ops::function::FnOnce::call_once
at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library/core/src/ops/function.rs:250:5
잘못된 참조로 발생하는 panic!() 에러
명시적으로 panic!()
을 호출하지 않아도, 프로그램 실행 중 잘못된 참조를 하면 내부에서 panic!()
에러가 발생합니다.
- 아래 예제는 존재하지 않는 index 99의 값을 참조 시도 시 panic 발생
fn main() {
let v = vec![1, 2, 3];
v[99];
}
Output:
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', src/main.rs:3:5
stack backtrace:
0: rust_begin_unwind
at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library/std/src/panicking.rs:579:5
1: core::panicking::panic_fmt
at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library/core/src/panicking.rs:64:14
2: core::panicking::panic_bounds_check
at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library/core/src/panicking.rs:159:5
3: <usize as core::slice::index::SliceIndex<[T]>>::index
at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library/core/src/slice/index.rs:260:10
4: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library/core/src/slice/index.rs:18:9
5: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library/alloc/src/vec/mod.rs:2703:9
6: RustExample::main
at ./src/main.rs:3:5
2. 복구 가능한 에러(Recoverable Error)
일부 함수들은 수행 결과를 Result
로 리턴합니다.
Result는 함수의 성공 여부를 Ok
와 Err
로 표현하며, Ok
는 정상적인 리턴 값이 포함되며, Err
은 에러가 포함됩니다.
즉, Result로부터 실행 결과가 성공했는지 체크하고 결과 값을 꺼내서 사용해야 합니다.
enum Result<T, E> {
Ok(T),
Err(E),
}
File open 예제
File::open(path)
은 path의 파일을 열고 Result<File>
로 결과를 리턴합니다.
- File이 존재하면 리턴 값은
Ok(file)
이 되고, 존재하지 않으면Err(error)
가 됩니다. match
문을 이용하여 Result Ok일 때 File을 변수에 할당하며, Err일 때는 panic을 발생시켜 프로그램을 종료시킴
use std::fs::File;
fn main() {
let f = File::open("hello.txt");
let f: File = match f {
Ok(file) => file,
Err(error) => {
panic!("There was a problem opening the file: {:?}", error)
},
};
}
unwrap()으로 예외처리
위의 예제는 match를 사용하여 코드가 좀 길어졌는데, unwrap()
을 사용하면 아래와 같이 짧게 구현할 수 있습니다.
unwrap()
은 Result가 Ok일 때 File 값을 리턴하여 변수에 할당하며, Err일 때panic!
을 발생시킴
use std::fs::File;
fn main() {
let f = File::open("hello.txt");
let f: File = f.unwrap();
}
파일이 존재하지 않을 때 아래와 같이 panic이 발생합니다.
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/main.rs:6:21
stack backtrace:
expect()으로 예외처리
expect()
도 unwrap()
과 동일한 역할을 합니다. 하지만 expect()
의 경우, panic이 발생했을 때 함께 보여줄 메시지를 인자로 전달할 수 있습니다.
use std::fs::File;
fn main() {
let f = File::open("hello.txt");
let f: File = f.expect("something wrong, crash");
}
파일이 존재하지 않을 때 아래와 같이 panic이 발생합니다.
thread 'main' panicked at 'something wrong, crash: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/main.rs:6:21
stack backtrace:
Related Posts
- Rust - String을 char 리스트(Vector)로 변환
- Rust - 문자가 대문자인지 소문자인지 확인
- Rust - String에서 줄바꿈(newline) 문자 제거 방법
- Rust - String 대문자, 소문자 변환
- Rust - 현재 시간 가져오기 (DateTime, chrono)
- Rust - 예외 처리 방법 (Exception handling)
- Rust - String.find()으로 문자열 Index 찾기
- Rust - match (Switch) 사용 방법
- Rust - Vector의 요소 제거 방법 (remove, retain, drain)
- Rust - String의 특정 Index 값 가져오기
- Rust - 문자열 뒤집기, 역순으로 변경
- Rust - String 객체에 문자열 추가하기
- Rust - sleep(), 몇 초 지연/대기 방법
- Rust - String을 Int, Float으로 변환
- Rust - Integer를 String으로 변환
- Rust - Float를 String으로 변환
- Rust - String 비교 방법 (==, !=, eq, ne)
- Rust - String을 str으로, str을 String으로 변환
- Rust - String 공백 제거 (trim, replace)
- Rust - 2개의 배열이 같은지 비교 (==, equals)
- Rust - 배열 길이 가져오기 (Array length)
- Rust - Vector를 배열로 변환 (vector to array)
- Rust - 배열의 최소, 최대 값 찾기 (min, max)
- Rust - 배열의 합계, 평균 (sum, average)
- Rust - 2개의 Vector가 같은지 비교 (==, equals)
- Rust - HashMap을 Vector로 변환
- Rust - Vector의 최소, 최대 값 찾기 (min, max)
- Rust - Vector의 합계, 평균 (sum, average)
- Rust - 벡터 길이 가져오기 (Vector length)
- Rust - 배열을 HashSet으로 변환
- Rust - 배열을 벡터로 변환하는 방법
- Rust - 배열(벡터) 모든 요소 출력
- Rust - 배열 나누기, 자르기 (split_at, slice)
- Rust - 2개 벡터 하나로 합치기
- Rust - HashSet을 Vector로 변환