여러 에러 타입
이전 예제들은 항상 매우 편리했습니다. Result는 다른 Result와 상호작용하고, Option은 다른 Option과 상호작용했습니다.
때때로는 Option이 Result와 상호작용해야 하거나, Result<T, Error1>이 Result<T, Error2>와 상호작용해야 할 때가 있습니다. 그런 경우, 우리는 서로 다른 에러 타입들을 구성 가능하고 상호작용하기 쉬운 방식으로 관리하고 싶어 합니다.
다음 코드에서, 두 개의 unwrap 인스턴스는 서로 다른 에러 타입을 생성합니다. Vec::first는 Option을 반환하는 반면, parse::<i32>는 Result<i32, ParseIntError>를 반환합니다:
fn double_first(vec: Vec<&str>) -> i32 {
let first = vec.first().unwrap(); // 에러 1 발생
2 * first.parse::<i32>().unwrap() // 에러 2 발생
}
fn main() {
let numbers = vec!["42", "93", "18"];
let empty = vec![];
let strings = vec!["두부", "93", "18"];
println!("두 배가 된 첫 번째 값은 {}입니다", double_first(numbers));
println!("두 배가 된 첫 번째 값은 {}입니다", double_first(empty));
// 에러 1: 입력 벡터가 비어 있습니다
println!("두 배가 된 첫 번째 값은 {}입니다", double_first(strings));
// 에러 2: 요소를 숫자로 파싱할 수 없습니다
}
다음 섹션들에서 이러한 종류의 문제들을 처리하기 위한 몇 가지 전략을 살펴볼 것입니다.