러스트의 에러와 예외 처리 방법에 대해서 알아보겠습니다.
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:52. 복구 가능한 에러(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 - String 비교 방법 (==, !=, eq, ne)
- Rust - Float를 String으로 변환
- Rust - Integer를 String으로 변환
- Rust - String을 str으로, str을 String으로 변환
- Rust - String 공백 제거 (trim, replace)
- Rust - 배열 길이 가져오기 (Array length)
- Rust - 2개의 배열이 같은지 비교 (==, equals)
- Rust - Vector를 배열로 변환 (vector to array)
- Rust - 배열의 최소, 최대 값 찾기 (min, max)
- Rust - 배열의 합계, 평균 (sum, average)
- Rust - 2개의 Vector가 같은지 비교 (==, equals)
- Rust - 배열을 HashSet으로 변환
- Rust - HashMap을 Vector로 변환
- Rust - Vector의 최소, 최대 값 찾기 (min, max)
- Rust - Vector의 합계, 평균 (sum, average)
- Rust - 벡터 길이 가져오기 (Vector length)
- Rust - 배열을 벡터로 변환하는 방법
- Rust - 배열(벡터) 모든 요소 출력
- Rust - 배열 나누기, 자르기 (split_at, slice)
- Rust - 2개 벡터 하나로 합치기
- Rust - HashSet을 Vector로 변환