Menu
Coddy logo textTech

물음표 연산자 '?'

Coddy Rust 여정의 Logic & Flow 섹션에 포함된 레슨 — 66개 중 46번째.

Result를 반환하는 함수를 다룰 때, 에러를 로컬에서 처리하거나 호출한 함수로 전달하여 처리해야 하는 경우가 많습니다. 러스트(Rust)는 이러한 일반적인 패턴을 위해 우아한 연산자인 물음표 연산자 ?를 제공합니다.

? 연산자는 장황한 match 문을 작성하지 않고도 에러를 전파할 수 있는 깔끔한 방법을 제공합니다. Result 뒤에 ?를 붙이면, 자동으로 Ok 값을 언랩(unwrap)하거나 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를 반환하면, ?는 즉시 전체 함수에서 해당 에러를 반환합니다.

? 연산자는 에러를 반환할 수 있어야 하므로, Result(또는 Option)를 반환하는 함수에서만 사용할 수 있습니다.

challenge icon

챌린지

쉬움

두 개의 입력을 받게 됩니다. 첫 번째 입력은 정수로 파싱되어야 하는 문자열이고, 두 번째 입력 또한 정수로 파싱되어야 하는 문자열입니다. 두 개의 문자열 슬라이스를 매개변수로 받고 Result<i32, std::num::ParseIntError>를 반환하는 add_numbers라는 함수를 만드세요. 함수 내부에서 ? 연산자를 사용하여 두 문자열을 모두 파싱하고, 그 합계를 Ok로 감싸서 반환하세요. 두 입력을 사용하여 함수를 호출하고 match를 사용하여 결과를 처리하세요.

요구 사항:

  • 첫 번째 입력(문자열 형태의 첫 번째 숫자)을 읽고 공백을 제거합니다.
  • 두 번째 입력(문자열 형태의 두 번째 숫자)을 읽고 공백을 제거합니다.
  • 두 개의 &str 매개변수를 받고 Result<i32, std::num::ParseIntError>를 반환하는 add_numbers 함수를 만듭니다.
  • 함수 내부에서 ? 연산자를 사용하여 첫 번째 문자열을 i32로 파싱합니다.
  • ? 연산자를 사용하여 두 번째 문자열을 i32로 파싱합니다.
  • 두 파싱된 숫자의 합계인 Ok(sum)을 반환합니다.
  • 두 입력 문자열을 사용하여 함수를 호출합니다.
  • match 표현식을 사용하여 Result를 처리합니다.
  • Ok(value) 암(arm)에서는 Sum: [value]를 출력합니다.
  • Err(_) 암(arm)에서는 Parsing error를 출력합니다.

입력:

  • 첫 번째 줄: 숫자를 나타내는 문자열 (예: 15)
  • 두 번째 줄: 또 다른 숫자를 나타내는 문자열 (예: 27)

출력:

  • 두 문자열이 모두 유효한 숫자인 경우: Sum: [result]
  • 어느 한 문자열이라도 파싱할 수 없는 경우: Parsing error

치트 시트

물음표 연산자 ?Result를 반환하는 함수에서 에러를 전파하는 간결한 방법을 제공합니다.

Result 뒤에 위치할 때, ? 연산자는 다음과 같이 동작합니다:

  • Ok 값을 언랩(unwrap)하고 실행을 계속합니다
  • 에러가 발생하면 현재 함수에서 즉시 Err를 반환합니다
fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> {
    let number = s.parse::<i32>()?; // 파싱에 실패하면 에러를 반환합니다
    Ok(number * 2) // 성공하면 숫자를 두 배로 만듭니다
}

? 연산자는 Result 또는 Option 타입을 반환하는 함수에서만 사용할 수 있습니다.

직접 해보기

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]"를 출력하세요
    // Err(_)인 경우 "Parsing error"를 출력하세요
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Logic & Flow의 모든 레슨