Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

17. 실무 모범 사례 (Best Practices) 🟡

학습 목표:

  • 관용적인(Idiomatic) Rust 코드를 작성하기 위한 실전 가이드라인을 마스터합니다.
  • 효율적인 코드 구조화, 안전한 에러 처리 패턴, 메모리 최적화 기법을 익힙니다.
  • 표준 트레이트들을 적재적소에 구현하여 "Rust다운" 프로그램을 만드는 방법을 알아봅니다.

1. 에러 처리의 정석

Rust에서 패닉(panic!)은 최후의 수단입니다. 일반적인 실패 상황은 반드시 ResultOption으로 처리하세요.

  • unwrap() 대신 안전한 대안 사용: 100% 성공이 보장되지 않는다면 unwrap()을 지양하세요.
    • unwrap_or(default): 기본값 제공
    • unwrap_or_else(|| ...): 지연 평가를 통한 기본값 생성 (비용 절감)
    • expect("메시지"): 실패 이유를 명확히 적어 디버깅 지원
  • 에러 전파와 체이닝: ? 연산자를 사용해 에러를 상위로 전파하세요.
  • 라이브러리 vs 애플리케이션:
    • thiserror: 라이브러리 개발 시, 구체적인 에러 타입(enum)을 정의할 때 필수입니다.
    • anyhow: 애플리케이션 최상위나 프로토타이핑에서 여러 에러를 하나로 묶어 처리할 때 유용합니다.

2. 메모리 및 성능 최적화

  • 빌림(Borrowing) 우선: 소유권 이동(Move)이나 복제(Clone)가 꼭 필요한 경우가 아니라면 참조(&T) 사용을 기본으로 하세요.
  • String vs &str: 데이터를 소유해야 하면 String, 읽기 전용으로 참조만 한다면 &str을 쓰세요. 함수 인자로는 &str이 훨씬 유연합니다.
  • 반복자(Iterator) 활용: 수동 루프(for i in 0..n)보다 반복자 체인이 대개 더 빠르고 안전합니다. (루프 퓨전 최적화 덕분)
  • 최적화 원칙: 추측하지 말고 프로파일링(cargo bench, flamegraph) 결과에 기반해 개선하세요.

3. 필수 트레이트 구현 체크리스트

커스텀 구조체를 설계할 때 다음 트레이트들을 구현하면 Rust 생태계와 자연스럽게 어우러집니다.

트레이트추천도설명
Debug필수{:?}로 출력 가능. 모든 커스텀 타입에 강력 추천
Display선택{}로 출력. 사용자에게 보여줄 친화적인 포맷팅
Clone권장명시적인 데이터 복제가 필요한 경우
Copy신중숫자, 불리언 등 단순 타입의 암시적 복사 (힙 데이터 있으면 금지)
Default권장합리적인 초기값이 있는 경우. ..Default::default() 문법 활용
From, Into권장타입 간의 안전한 변환 제공 (From만 구현하면 Into는 자동 생성)
#![allow(unused)]
fn main() {
// 전형적인 모범 사례 구조체 정의
#[derive(Debug, Clone, PartialEq, Default, serde::Serialize)]
pub struct UserConfig {
    pub id: u64,
    pub name: String,
    pub is_active: bool,
}
}

4. 코드 품질과 문서화

  • 공개 API 문서화: ///를 사용해 문서 주석을 작성하세요. cargo doc으로 사내 기술 문서를 자동 생성할 수 있습니다.
  • 모듈화: 파일 하나가 너무 커지기 전에 기능을 분리하고 가시성(pub, pub(crate))을 명확히 하세요.
  • 테스트 동반: 로직이 있는 모든 함수 옆에 유닛 테스트(#[cfg(test)])를 작성하는 습관을 들이세요.

💡 한 줄 조언

"Rust 코드가 컴파일 에러를 내뱉는 것은 당신을 괴롭히려는 것이 아니라, 나중에 발생할 끔찍한 런타임 버그로부터 당신을 미리 구하려는 것입니다. 컴파일러와 덤벼서 싸우지 말고, 컴파일러의 조언에 귀를 기울이세요."


📌 요약

  • 에러는 **Result**로 명시적으로 다루세요.
  • 불필요한 **Clone**을 줄여 메모리 효율을 높이세요.
  • 핵심 트레이트들을 구현해 표준 라이브러리와의 호환성을 높이세요.
  • 유닛 테스트문서화는 코드의 생명주기를 연장하는 가장 좋은 방법입니다.