C.W.K.
Stream
Lesson 02 of 05 · published

Result — 복구 가능 에러

~11 min · errors, result, recoverable

Level 0Rust 호기심러
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

대부분 실패는 버그가 아니야 — 파일이 없을 수도, 입력이 잘못됐을 수도, 네트워크 호출이 타임아웃 날 수도. 얘들은 복구 가능 하고, Rust 는 Result<T, E> 로 값으로 모델링해.

Result, 다시

Enums 트랙에서 Result 를 enum 으로 만났어: 성공엔 Ok(T), 이유 있는 실패엔 Err(E). 표준 라이브러리는 실패 가능한 모든 것에서 그걸 반환해: str::parse, File::open, 모든 I/O 호출. 호출자는 Err 경우와 마주해야 해 — 컴파일러가 조용히 빠져나가게 안 둬.

Result 처리하기

아는 도구로 처리해: Ok/Errmatch, 또는 map, map_err, unwrap_or, unwrap_or_else 같은 combinator. Option 과의 핵심 차이는 E 야: 실패했다는 사실 만 아는 게 아니라 인지 알고, 이유로 분기할 수 있어.

에러는 코드를 흐르는 값이야. 숨은 제어 흐름도, 세 프레임 위로 보이지 않게 던지는 것도 없어. 실패할 수 있는 함수는 반환 타입으로 그렇다고 말하고, 실패는 네가 match 하고, map 하고, 전파할 수 있는 평범한 값으로 여행해. 선언한 적 없는 에러에 놀랄 수 없어.

장황함 문제

모든 Result 를 손으로 match 하면 금방 지겨워 — 특히 함수가 실패 가능한 것 다섯 개를 부르고 첫 실패에 빠지고 싶을 때. 그 지겨움이 바로 ? 연산자 (다음 레슨) 가 없애는 거야, 다섯 줄 match 를 한 글자로.

Code

Result: 성공 또는 실패의 이유·rust
use std::num::ParseIntError;

fn double(s: &str) -> Result<i32, ParseIntError> {
    match s.trim().parse::<i32>() {
        Ok(n) => Ok(n * 2),
        Err(e) => Err(e), // 실패 이유를 넘겨줌
    }
}

fn main() {
    match double("21") {
        Ok(n) => println!("got {n}"),
        Err(e) => println!("failed: {e}"),
    }
    // fallback 있는 combinator 스타일:
    let n = double("oops").unwrap_or(0);
    println!("{n}");
}

External links

Exercise

float 을 파싱하고 실패 시 설명적인 Err(String) 을 반환하는 fn parse_temp(s: &str) -> Result<f64, String> 를 써봐 (.map_err 사용). main 에서 match 로 결과를 처리하고 성공/실패에 다른 메시지를 출력해. 여기서 panic 보다 Result 반환이 왜 나아?
Hint
잘못된 사용자 입력은 예상된 복구 가능 조건이야 — 호출자가 뭘 할지 정해야 해 (재입력, 기본값, 로그). panic 은 오타 하나에 프로그램 전체를 크래시해. Result 는 결정을 호출자한테 넘겨.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 똘이warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.