`Result`를 활용한 견고한 오류 처리
`Result` 열거형, `?` 연산자, 사용자 정의 오류 형식을 사용해 관용적인 오류 처리를 구현하고 복원력 있는 애플리케이션을 만듭니다.
`Result`를 활용한 견고한 오류 처리은(는) CoddyKit의 무료 Learn Rust Coding 강의입니다. 이것은 3개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Learn Rust Coding 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Learn Rust Coding 강의에는 총 3개의 강의가 포함되어 있습니다.
Rust에서 오류 처리하기
오류는 프로그래밍의 일부입니다. Rust에서는 오류를 크게 복구 가능한 오류와 복구할 수 없는 오류로 구분합니다.
- 복구할 수 없는 오류는 대개 버그를 나타내며,
panic!으로 프로그램이 중지됩니다. - 복구 가능한 오류는 파일을 찾을 수 없는 경우처럼 문제가 발생했지만 처리할 수 있는 상황을 의미합니다.
Rust는 복구 가능한 오류를 우아하게 처리할 수 있도록 도와줍니다.
`panic!`과 `Result` 비교
복구할 수 없는 오류가 발생하면 Rust는 panic! 매크로를 호출합니다. 그러면 스택을 해제하고 프로그램을 종료하며, 일반적으로 오류 메시지를 출력합니다.
복구 가능한 오류에는 Rust의 Result 열거형을 사용합니다. 이 열거형은 작업이 성공했는지(Ok) 실패했는지(Err) 알려 주므로, 프로그램이 다음에 수행할 작업을 결정할 수 있습니다.
`Result` 열거형
Result 열거형은 개념적으로 다음과 같이 정의됩니다.
enum Result<T, E> {
Ok(T),
Err(E),
}
T는 성공 시 반환되는 값의 유형을 나타냅니다.E는 실패 시 반환되는 오류의 유형을 나타냅니다.
이는 함수가 실패할 수도 있다는 사실을 명시적으로 나타내는 강력한 방법입니다.
`Result`에 패턴 매칭 사용하기
Result를 처리하는 가장 일반적인 방법은 match 표현식을 사용하는 것입니다. 이를 통해 Result가 Ok인지 Err인지에 따라 서로 다른 코드 블록을 실행할 수 있습니다.
숫자 구문 분석을 시도하는 다음 예제를 실행해 보십시오.
fn parse_and_add(text: &str) -> Result<i32, std::num::ParseIntError> {
text.parse::<i32>()
}
fn main() {
let num_str = "123";
let result = parse_and_add(num_str);
match result {
Ok(num) => println!("Parsed number: {}", num),
Err(e) => println!("Error parsing: {}", e),
}
let bad_str = "abc";
let bad_result = parse_and_add(bad_str);
match bad_result {
Ok(num) => println!("Parsed number: {}", num),
Err(e) => println!("Error parsing: {}", e),
}
}Result 값 꺼내기(주의해서 사용하기!)
때로는 작업이 실패하지 않을 것이라고 확신하거나, 실패할 경우 프로그램을 중단하고 싶을 수 있습니다. unwrap() 및 expect()와 같은 메서드는 Ok 값을 추출합니다.
unwrap():Ok값을 반환하거나Err이면 패닉을 발생시킵니다.expect("message"):unwrap()과 같지만 사용자 지정 패닉 메시지를 지정할 수 있습니다.
이 기능은 주로 테스트에서 사용하거나 실패가 정말로 복구할 수 없는 경우에만 제한적으로 사용하십시오.
`?` 연산자 소개
모든 Result에 대해 match 문을 작성하면 반복적인 코드가 될 수 있습니다. ? 연산자는 오류 전파를 간결하게 처리하는 방법을 제공합니다.
Result를 반환하는 표현식 뒤에 ?를 사용하면 다음 두 가지 작업을 수행합니다.
Result가Err이면 현재 함수에서 즉시 해당Err를 반환합니다.Result가Ok이면Ok값을 꺼내고 실행을 계속합니다.
`?` 연산자 실제 사용
? 연산자를 사용하면 실패할 수 있는 함수를 훨씬 깔끔하게 작성할 수 있습니다. ?를 사용하는 함수 자체가 Result(또는 Option)를 반환해야 한다는 점을 기억하십시오.
파일을 읽는 다음 예제에서 ?가 오류 처리를 어떻게 단순화하는지 살펴보십시오.
use std::fs::File;
use std::io::{self, Read};
fn read_username_from_file() -> Result<String, io::Error> {
let mut f = File::open("hello.txt")?; // Propagates error if file not found
let mut s = String::new();
f.read_to_string(&mut s)?; // Propagates error if read fails
Ok(s)
}
fn main() {
// Create a dummy file for the example to work
// In a real scenario, this file might not exist
std::fs::write("hello.txt", "CoddyKit User").unwrap();
match read_username_from_file() {
Ok(username) => println!("Username: {}", username),
Err(e) => println!("Error reading username: {}", e),
}
// Clean up the dummy file
std::fs::remove_file("hello.txt").unwrap();
}사용자 지정 오류 유형
때로는 기본 제공 오류 유형만으로는 충분히 구체적으로 표현할 수 없습니다. 열거형을 사용해 자신만의 사용자 지정 오류 유형을 정의하고 애플리케이션에서 발생할 수 있는 여러 실패 상황을 나타낼 수 있습니다.
이렇게 하면 오류 메시지가 더 명확해지고, 호출자가 특정 오류를 서로 다르게 처리할 수 있습니다.
일반적인 방식은 함수나 모듈에서 발생할 수 있는 모든 오류를 나열하는 열거형을 만드는 것입니다.
사용자 지정 오류에서 `?` 사용하기
? 연산자가 하위 수준의 오류(예: io::Error)를 사용자 지정 오류 유형으로 자동 변환하려면, 사용자 지정 오류 열거형이 해당 하위 수준 오류에 대한 From 트레이트를 구현해야 합니다.
이를 통해 Rust는 한 오류 유형을 다른 유형으로 변환하는 방법을 알 수 있으므로 오류를 매끄럽게 전파할 수 있습니다.
use std::io;
use std::fs::File;
use std::io::Read;
#[derive(Debug)]
enum MyError {
Io(io::Error),
Parse(std::num::ParseIntError)
}
impl From<io::Error> for MyError {
fn from(error: io::Error) -> Self {
MyError::Io(error)
}
}
impl From<std::num::ParseIntError> for MyError {
fn from(error: std::num::ParseIntError) -> Self {
MyError::Parse(error)
}
}
fn read_config(path: &str) -> Result<i32, MyError> {
let mut file = File::open(path)?; // io::Error converted to MyError::Io
let mut contents = String::new();
file.read_to_string(&mut contents)?; // io::Error converted to MyError::Io
let value = contents.trim().parse::<i32>()?; // ParseIntError converted to MyError::Parse
Ok(value)
}
fn main() {
// Create a dummy file for the example
std::fs::write("config.txt", "123").unwrap();
match read_config("config.txt") {
Ok(val) => println!("Config value: {}", val),
Err(e) => println!("Failed to read config: {:?}", e),
}
std::fs::remove_file("config.txt").unwrap(); // Clean up
// Example with a non-existent file
match read_config("non_existent.txt") {
Ok(val) => println!("Config value: {}", val),
Err(e) => println!("Failed to read config: {:?}", e),
}
}이해도 확인
다음 Rust 코드 조각을 살펴보십시오. data.txt 파일이 존재하지 않을 경우 출력 결과는 무엇입니까?
복습: 견고한 오류 처리
Rust에서 견고한 오류 처리를 익혔습니다!
Result열거형: 성공을 나타내는Ok(T)와 실패를 나타내는Err(E)를 구분합니다.match:Result변형을 처리하는 기본적인 방법입니다.?연산자:Err값을 호출 스택 위로 전파하는 강력한 지름길입니다.- 사용자 지정 오류: 명확하고 구체적인 처리를 위해 열거형으로 자신만의 오류 유형을 정의합니다.
From트레이트:?를 사용할 때 하위 수준의 오류를 사용자 지정 오류 유형으로 매끄럽게 변환할 수 있게 합니다.
다음으로 고급 유형 시스템 기능을 살펴보십시오!
AI 튜터와 함께 Rust을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 39
- 레슨
- 144
자주 묻는 질문
“`Result`를 활용한 견고한 오류 처리” 강의는 무료인가요?
네 — “`Result`를 활용한 견고한 오류 처리” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Learn Rust Coding 강의 전체를 잠금 해제할 수 있습니다. Learn Rust Coding 강의에는 총 3개의 강의가 포함되어 있습니다.
“`Result`를 활용한 견고한 오류 처리”에서 뭘 배우나요?
`Result` 열거형, `?` 연산자, 사용자 정의 오류 형식을 사용해 관용적인 오류 처리를 구현하고 복원력 있는 애플리케이션을 만듭니다. 브라우저에서 직접 실행하는 실습 코드로 Learn Rust Coding을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Learn Rust Coding을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Learn Rust Coding은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 3번째 강의입니다.
“`Result`를 활용한 견고한 오류 처리” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Learn Rust Coding 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Learn Rust Coding 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 모듈로 코드 구성하기
- 크레이트로 의존성 관리하기
- `Result`를 활용한 견고한 오류 처리