물음표 연산자 '?'
Coddy Rust 여정의 논리와 흐름 섹션에 포함된 레슨. 66개 중 46번째.
Result를 반환하는 함수로 작업할 때는 오류를 로컬에서 처리하거나 호출하는 함수로 전달하여 처리해야 하는 경우가 많습니다. Rust는 이러한 일반적인 패턴을 위한 우아한 연산자인 물음표 연산자 ?를 제공합니다.
? 연산자는 장황한 match 문을 작성하지 않고도 오류를 깔끔하게 전파하는 방법을 제공합니다. Result 뒤에 ?를 배치하면 Ok 값을 자동으로 언래핑하거나 현재 함수에서 즉시 Err와 함께 반환합니다:
fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> {
let number = s.parse::<i32>()?; // 파싱에 실패하면 오류를 반환합니다
Ok(number * 2) // 성공하면 숫자를 두 배로 만듭니다
}이는 전체 match 문을 작성하는 것과 동등하지만 훨씬 더 간결합니다. s.parse::<i32>()가 Ok를 반환하면 ?가 값을 추출하여 number에 할당합니다. Err를 반환하면 ?가 해당 오류를 전체 함수에서 즉시 반환합니다.
::<i32> 구문에 주목하세요. 이를 turbofish라고 하며, Rust가 문자열을 어떤 타입으로 parse해야 하는지 알려 줍니다. function은 Result<i32, std::num::ParseIntError>를 반환합니다. 여기서 i32는 성공 타입이고 std::num::ParseIntError는 parsing이 fails할 때 반환되는 error 타입입니다.
? 연산자는 오류를 반환할 수 있어야 하므로 Result(또는 Option)를 반환하는 함수에서만 사용할 수 있습니다.
챌린지
쉬움두 개의 입력을 받습니다. 첫 번째 입력은 정수로 파싱해야 하는 문자열이고, 두 번째 입력은 역시 정수로 파싱해야 하는 또 다른 문자열입니다. 두 문자열 슬라이스를 parameters로 받고 Result<i32, std::num::ParseIntError>를 반환하는 add_numbers이라는 function을 Create하세요. function 내부에서 ? 연산자를 사용하여 두 문자열을 파싱하고, 그 합을 Ok으로 감싸서 return하세요. 두 입력으로 function을 Call하고 match를 사용하여 result를 handle하세요.
요구 사항:
- 첫 번째 input(문자열로 된 first number)을 read하고 공백을 trim하세요
- 두 번째 input(문자열로 된 second number)을 read하고 공백을 trim하세요
- 두 개의
&strparameters를 받고Result<i32, std::num::ParseIntError>를 반환하는add_numbersfunction을 Create하세요 - function 내부에서
?연산자를 사용하여 first string을i32로 parse하세요 ?연산자를 사용하여 second string을i32로 parse하세요- 파싱된 두 number의 덧셈인
Ok(sum)을 return하세요 - 두 input strings로 function을 Call하세요
Result를 handle하기 위해matchexpression을 사용하세요Ok(value)arm에서Sum: [value]를 출력하세요Err(_)arm에서Parsing error를 출력하세요
Input:
- 첫 번째 line: number를 나타내는 string(예:
15) - 두 번째 line: 또 다른 number를 나타내는 string(예:
27)
Output:
- 두 strings가 모두 유효한 numbers인 경우:
Sum: [result] - 어느 한 string이라도 파싱할 수 없는 경우:
Parsing error
직접 해보기
use std::io;
// TODO: 여기에 add_numbers 함수를 작성하세요
// 두 개의 &str 매개변수를 받아 Result<i32, std::num::ParseIntError>를 반환해야 합니다
fn main() {
// 첫 번째 입력 읽기
let mut input1 = String::new();
io::stdin().read_line(&mut input1).expect("Failed to read line");
let input1 = input1.trim();
// 두 번째 입력 읽기
let mut input2 = String::new();
io::stdin().read_line(&mut input2).expect("Failed to read line");
let input2 = input2.trim();
// TODO: input1과 input2로 add_numbers 호출
// TODO: match를 사용하여 Result 처리
// Ok(value)인 경우 "Sum: [value]" 출력
// Print "Parsing error" for Err(_)
}이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
논리와 흐름의 모든 레슨
7'Result'를 이용한 에러 처리
'Result'란 무엇인가요?'Result'와 함께 'match' 사용하기is_ok()와 is_err()단축 방법: unwrap과 expect물음표 연산자 '?'문자열을 숫자로 파싱하기요약 - 안전한 나눗셈 함수직접 연습해 보세요: 온라인 Rust 컴파일러