
Result는 enum타입으로, Ok (정상 결과) 혹은 Err(오류 결과)를 가집니다. 즉, 정상, 오류 둘 중 하나로 평가된다고 보면 쉽습니다. 원형을 보면 다음과 같습니다.
enum Result<T, E> {
Ok(T),
Err(E),
}
제네릭으로 표현된 Result<T, E>는 Ok로 반환하고 싶은 것과 Err로 반환하고 싶은 것을 결정해야 한다는 의미입니다. Ok로 T타입의 값을 감싸서 반환하거나, Err로 E타입의 값을 감싸서 반환하는 열거형인 셈입니다.
여기서 감싸다(wrap)는 표현이 자주 쓰이는데요, Ok(1)과 그냥 1의 차이는 무엇일까요?
Ok(1)은 1을 반환하는데 성공했다는 메시지와, 값을 감싼 상자라고 이해하면 쉽습니다. 반면에 1은 말 그대로 그냥 1이라는 값입니다. Ok(1)을 굳이 비유하자면, 내부 동작 메커니즘은 다르지만 자바스크립트의 Promise.resolve(1)과 유사하다고 보면 됩니다. 1이라는 값에 접근하기 위해서는 Promise.resolve(1)에 await키워드나 .then같은 메서드를 사용해서 fulfill된 값을 추출하는 것 처럼, Rust의 Ok(1) 또한 감싼것을 풀어내는 작업이 필요합니다. 이 역할을 해주는 함수가 바로 unwrap()입니다.
unwrap은 Result타입이 가지는 함수로, Ok에 감싸진 값 또는 Err에 감싸진 에러를 말 그대로 풀어내는, unwrap 해버리는 함수입니다. unwrap이 호출되는 순간에는 이 상자가 Ok인지 Err인지 모르기 때문에, 풀어낼 대상이 Ok라면 프로그램은 정상 작동하고, Err라면 패닉합니다. 쉬운 예제를 통해 코드레벨에서 살펴보겠습니다.
fn main() {
// 1. 일반 값
let number = 1;
println!("일반 값: {}", number); // 그냥 1 출력
// 2. Ok로 감싼 값
let result = Ok(1);
println!("Result 타입: {:?}", result); // Ok(1) 출력
// 3. unwrap으로 값 추출
let unwrapped = result.unwrap();
println!("unwrap 후: {}", unwrapped); // 1 출력
}
만약 unwrap하는 대상이 Err라면, 프로그램은 패닉에 빠지고 종료됩니다.
fn main() {
let error_result:Result<i32, &str> = Err("에러 발생");
let value = error_result.unwrap(); //❌ 패닉 발생, 프로그램 종료
}
# 에러 메시지
thread 'main' panicked at src/main.rs:3:34:
called `Result::unwrap()` on an `Err` value: "에러 발생"
이를 방지하기 위해 match라는 흐름 제어 키워드를 사용할 수 있습니다. try-catch문인 셈입니다.
fn main() {
let result: Result<String, &str> = Err("에러 발생!");
match result { // result를 풀어본 결과가
Ok(value) => println!("성공: {}", value), // Ok라면 이거 하고,
Err(e) => println!("에러: {}", e) // Err라면 이거 해줘요.
}
}
에러: 에러 발생
expect는 unwrap과 동일하게 Result타입 값을 풀어내는 역할을 수행합니다. 하지만 expect는 Rust의 기본 에러 메세지 대신 커스텀 메세지를 예약할 수 있습니다.
fn main() {
let error_result:Result<i32, &str> = Err("메롱");
let value = error_result.expect("일부러 발생시킨 에러입니다: "); //❌ 패닉 발생, 프로그램 종료
}
thread 'main' panicked at src/main.rs:4:30:
일부러 발생시킨 에러입니다: : "메롱"
Result타입 값은 풀어내야 다룰 수 있고, 웬만해선match쓰세요
Result는 상자입니다. 상자는 풀어보기 전에 안에 무엇이 들어있는지 모르기 때문에unwrap또는expect로 풀어봐야 내용물을 다룰 수 있습니다.unwrap,expect는 풀어본 내용이Err라면 프로그램이 종료됩니다. 이것을 의도한 게 아니라면match를 써서 패닉을 방지하세요!