panic! 으로 복구 불가능한 에러 처리
- 실제 패닉을 일으키기 위해선 패닉을 일으킬만한 동작을 하거나 panic! 매크로를 명시적으로 호출한다.
- 패닉이 일어나면 실패 메시지 출력 > 되감기 > 스택 청소 > 종료
- 근원을 추적하기 위해 호출 스택을 보여주게 할수도 있다.
panic! 백트레이스
fn main() {
let v = vec![1, 2, 3];
v[99];
}
- 유효한 인덱스를 넘어서는 벡터 접근
- RUST_BACKTRACE 환경변수를 0이 아닌 값으로 변경한다.
enum Result<T, E> {
Ok(T),
Err(E),
}
Result 로 복구 가능한 에러 처리하기
use std::fs::File;
fn main() {
let greeting_file_result = File::open("hello.txt");
let greeting_file = match greeting_file_result {
Ok(file) => file,
Err(error) => panic!("Problem opening the file: {:?}", error),
};
}
- 파일은 열수 있거나 열지 못할수 있다.
- Result 자료형으로 반환해 성공시와 실패시를 나눌수 있다.
서로 다른 에러 매핑하기
use std::fs::File;
use std::io::ErrorKind;
fn main() {
let greeting_file_result = File::open("hello.txt");
let greeting_file = match greeting_file_result {
Ok(file) => file,
Err(error) => match error.kind() {
ErrorKind::NotFound => match File::create("hello.txt") {
Ok(fc) => fc,
Err(e) => panic!("Problem creating the file: {:?}", e),
},
other_error => {
panic!("Problem opening the file: {:?}", other_error);
}
},
};
}
unwrap_or_else
fn main() {
let greeting_file = File::open("hello.txt").unwrap_or_else(|error| {
if error.kind() == ErrorKind::NotFound {
File::create("hello.txt").unwrap_or_else(|error| {
panic!("Problem creating the file: {:?}", error);
})
} else {
panic!("Problem opening the file: {:?}", error);
}
});
}
숏컷 : unwrap, expect
unwrap
- Result 값이 Ok 일시 Ok 내부 값 반환
- Err 일시 panic! 매크로 호출
expect
- panic! 에러 메시지로 선택할수 있도록 해준다.
에러 전파하기
use std::fs::File;
use std::io::{self, Read};
fn read_username_from_file() -> Result<String, io::Error> {
let username_file_result = File::open("hello.txt");
let mut username_file = match username_file_result {
Ok(file) => file,
Err(e) => return Err(e),
};
let mut username = String::new();
match username_file.read_to_string(&mut username) {
Ok(_) => Ok(username),
Err(e) => Err(e),
}
}
?
use std::fs::File;
use std::io::{self, Read};
fn read_username_from_file() -> Result<String, io::Error> {
let mut username_file = File::open("hello.txt")?;
let mut username = String::new();
username_file.read_to_string(&mut username)?;
Ok(username)
}
- Reuslt 의 값이 Ok일시 Ok안의 값이 얻어짐
- Err일시 Err의 값이 반환된다.
- Result, Option, FromResidual 에만 사용 가능하다.
use std::error::Error;
use std::fs::File;
fn main() -> Result<(), Box<dyn Error>> {
let greeting_file = File::open("hello.txt")?;
Ok(())
}