🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Rust 주석과 문서화 완벽 가이드 - 슬라이드 1/9
A

AI Generated

2026. 3. 6. · 0 Views

Rust 주석과 문서화 완벽 가이드

Rust에서 코드를 설명하는 주석부터 자동 문서 생성까지 완벽하게 마스터하세요. 실무에서 바로 활용할 수 있는 문서화 스킬을 이북처럼 술술 읽히게 정리했습니다.


목차

  1. 한 줄 주석의 기본
  2. 여러 줄 주석 활용법
  3. 문서화 주석의 마법
  4. 모듈 문서화 주석
  5. 문서화 주석의 마크다운
  6. 문서 테스트의 힘
  7. 주석 스타일 가이드
  8. 주석과 리팩토링

1. 한 줄 주석의 기본

어느 날 김개발 씨가 처음으로 Rust 프로젝트에 참여하게 되었습니다. 선배 개발자가 작성한 코드를 보는데, 곳곳에 //로 시작하는 문장들이 눈에 띄었습니다.

"이게 다 뭐지? 실행에 영향을 주나?" 김개발 씨는 궁금증을 안고 선배에게 물어보았습니다.

한 줄 주석은 코드 내에 설명을 남기는 가장 기본적인 방법입니다. // 기호로 시작하며, 컴파일러는 이 부분을 완전히 무시합니다.

마치 코드에 메모를 남기는 것과 같습니다. 협업할 때 코드의 의도를 전달하는 핵심 도구입니다.

다음 코드를 살펴봅시다.

fn calculate_discount(price: u32, member_level: u32) -> u32 {
    // 회원 등급에 따른 할인율 계산
    // 레벨 1: 5%, 레벨 2: 10%, 레벨 3: 15%
    let discount_rate = match member_level {
        1 => 0.05,
        2 => 0.10,
        3 => 0.15,
        _ => 0.0,  // 비회원은 할인 없음
    };

    // 할인 금액 계산 후 반환
    let discount = (price as f64 * discount_rate) as u32;
    discount
}

김개발 씨가 첫 Rust 프로젝트에 투입된 지 일주일째. 혼자서 열심히 코드를 작성하던 중, 선배인 박시니어 씨가 다가왔습니다.

"김개발 씨, 이 코드 나중에 다른 사람이 봐도 이해할 수 있게 작성했어요?" 김개발 씨는 멈칫했습니다. 확실히 복잡한 계산 로직을 그냥 숫자만 나열했더니, 일주일 뒤에 자신이 봐도 무슨 의미인지 헷갈렸으니까요.

그때 박시니어 씨가 가르쳐준 것이 바로 한 줄 주석이었습니다. 주석이란 무엇일까요?

쉽게 말해 코드에 남기는 메모입니다. 마치 요리책에 "여기서 불을 약하게!"라고 적어두는 것과 같습니다.

컴파일러는 이 메모를 완전히 무시하고 지나칩니다. 하지만 나중에 코드를 읽는 사람에게는 보물 같은 정보가 됩니다.

주석이 없던 시절의 개발자들은 어떻게 했을까요? 복잡한 알고리즘을 이해하기 위해 종이에 수식을 적어가며 분석해야 했습니다.

팀원이 작성한 코드를 이해하려면 그 사람을 직접 찾아가서 물어봐야 했습니다. 프로젝트가 커질수록 이런 비효율은 눈덩이처럼 불어났습니다.

그래서 등장한 것이 주석입니다. 주석을 사용하면 코드 옆에 설명을 남길 수 있습니다.

"이 변수는 사용자의 로그인 상태를 저장합니다" 같은 설명을 코드 바로 옆에 적어두는 것이죠. 나중에 코드를 읽는 사람은 주석만 봐도 코드의 의도를 파악할 수 있습니다.

위의 코드를 자세히 살펴보겠습니다. 함수 시작 부분에 "회원 등급에 따른 할인율 계산"이라는 주석이 있습니다.

이 한 줄만 봐도 이 함수가 무슨 일을 하는지 바로 알 수 있습니다. 그 다음 줄에는 각 레벨별 할인율을 설명하는 주석이 있습니다.

숫자만 봐서는 0.05가 5%인지 0.5%인지 헷갈릴 수 있지만, 주석 덕분에 명확해집니다. 실무에서는 어떻게 활용할까요?

쇼핑몰 서비스를 개발한다고 가정해봅시다. 복잡한 할인 로직, 배송비 계산, 포인트 적립 규칙 등이 있습니다.

이런 로직에 주석을 달아두면, 나중에 기획팀에서 "이거 왜 이렇게 됐어요?"라고 물어볼 때 주석을 보며 자신 있게 설명할 수 있습니다. 하지만 주의할 점도 있습니다.

너무 당연한 내용을 주석으로 달면 오히려 방해가 됩니다. let x = 5; // x에 5를 대입 같은 주석은 아무 도움이 안 됩니다.

"왜" 이렇게 작성했는지, "무엇을" 의도하는지를 적어야 합니다. 김개발 씨는 박시니어 씨의 조언을 듣고 코드에 주석을 추가하기 시작했습니다.

나중에 자신이 작성한 코드를 다시 봤을 때, 주석 덕분에 빠르게 이해할 수 있었습니다. "주석은 미래의 나, 그리고 동료들을 위한 친절한 편지구나!"

실전 팁

💡 - "무엇을"보다 "왜"에 집중해서 주석을 작성하세요

  • 코드가 변경되면 주석도 함께 수정하는 습관을 들이세요

2. 여러 줄 주석 활용법

프로젝트가 진행되면서 김개발 씨는 더 복잡한 로직을 마주하게 되었습니다. 한두 줄로는 설명이 부족한 상황이 온 것입니다.

"이 알고리즘을 어떻게 설명하지?" 고민하던 차에 박시니어 씨가 여러 줄 주석을 소개해 주었습니다.

여러 줄 주석/*로 시작해서 */로 끝납니다. 그 사이에 있는 모든 내용은 주석으로 처리됩니다.

긴 설명이나 복잡한 알고리즘을 설명할 때 유용합니다. 마치 코드 안에 작은 문서를 작성하는 것과 같습니다.

다음 코드를 살펴봅시다.

fn binary_search(arr: &[i32], target: i32) -> Option<usize> {
    /*
     * 이진 탐색 알고리즘
     *
     * 시간 복잡도: O(log n)
     * 공간 복잡도: O(1)
     *
     * 전제 조건: 배열은 반드시 정렬되어 있어야 함
     * 반환값: 찾으면 인덱스, 없으면 None
     */
    let mut left = 0;
    let mut right = arr.len() - 1;

    while left <= right {
        let mid = left + (right - left) / 2;

        if arr[mid] == target {
            return Some(mid);
        } else if arr[mid] < target {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }

    None
}

김개발 씨가 맡은 작업은 검색 기능 최적화였습니다. 기존 코드는 처음부터 끝까지 하나씩 비교하는 방식이라 데이터가 많아지면 느려지는 문제가 있었습니다.

박시니어 씨가 말했습니다. "이진 탐색을 적용해 보세요.

대신 이 알고리즘은 전제 조건이 있어요." 이진 탐색이 무엇일까요? 마치 영어사전에서 단어를 찾는 것과 같습니다.

처음부터 한 페이지씩 넘기는 게 아니라, 중간을 펴보고 찾는 단어가 앞부분에 있으면 앞쪽을, 뒷부분에 있으면 뒷쪽을 탐색합니다. 이렇게 하면 탐색 범위가 매번 반으로 줄어들죠.

김개발 씨는 이진 탐색 코드를 작성했습니다. 하지만 문제가 있었습니다.

이 함수를 사용하는 다른 팀원들이 "왜 갑자기 검색이 안 되지?"라고 물어보는 것이었습니다. 알고 보니 이진 탐색은 정렬된 배열에서만 작동합니다.

이 중요한 정보를 전달하지 않았던 것입니다. 바로 이럴 때 여러 줄 주석이 필요합니다.

여러 줄 주석은 /*로 시작해서 */로 끝납니다. 그 사이에는 몇 줄이든 자유롭게 작성할 수 있습니다.

위 코드를 보면 알고리즘의 시간 복잡도, 공간 복잡도, 전제 조건, 반환값을 깔끔하게 정리했습니다. 이 주석을 읽는 개발자는 함수를 호출하기 전에 어떤 준비가 필요한지, 어떤 결과를 기대할 수 있는지 한눈에 파악할 수 있습니다.

마치 제품 설명서를 읽는 것과 같습니다. 실무에서는 복잡한 비즈니스 로직에 특히 유용합니다.

예를 들어 세금 계산 로직을 작성한다고 가정해봅시다. 관세, 부가세, 특소세 등 여러 세금이 복잡하게 얽혀 있습니다.

이럴 때 여러 줄 주석으로 계산 공식과 근거 법령을 적어두면, 나중에 세무팀에서 검수할 때 큰 도움이 됩니다. 주의할 점은 주석이 코드와 동기화되지 않는 경우입니다.

코드를 수정했는데 주석을 업데이트하지 않으면, 주석이 거짓말을 하게 됩니다. "이 함수는 O(n)입니다"라고 적어놓고 실제로는 O(n²)인 상황이 생기면 오히려 혼란을 줍니다.

김개발 씨는 여러 줄 주석을 통해 이진 탐색의 전제 조건을 명확히 전달했습니다. 이후 다른 팀원들이 이 함수를 사용할 때 "아, 정렬을 먼저 해야 하는구나!"라고 바로 이해할 수 있었습니다.

실전 팁

💡 - 알고리즘의 전제 조건과 시간 복잡도를 명시하세요

  • 코드 수정 시 주석도 함께 업데이트하는 것을 잊지 마세요

3. 문서화 주석의 마법

"김개발 씨, 우리 팀 API 문서 어디 있어요?" 기획팀의 물음에 김개발 씨는 당황했습니다. 코드는 작성했는데 따로 문서를 만들지 않았던 것입니다.

그때 박시니어 씨가 "Rust는 코드만으로 문서를 만들 수 있어요"라고 말했습니다.

문서화 주석/// 또는 //!로 시작합니다. 일반 주석과 달리, cargo doc 명령어로 아름다운 HTML 문서를 자동 생성할 수 있습니다.

마치 코드가 스스로 사용설명서를 작성하는 것과 같습니다.

다음 코드를 살펴봅시다.

/// 사용자 정보를 저장하는 구조체입니다.
///
/// # Examples
///
/// ```
/// let user = User::new("김개발", "kim@example.com");
/// assert_eq!(user.name, "김개발");
/// ```
#[derive(Debug)]
pub struct User {
    /// 사용자의 이름 (한글, 영문 모두 가능)
    pub name: String,
    /// 이메일 주소 (유효성 검사 필요)
    pub email: String,
}

impl User {
    /// 새로운 User 인스턴스를 생성합니다.
    ///
    /// # Arguments
    ///
    /// * `name` - 사용자 이름
    /// * `email` - 이메일 주소
    ///
    /// # Returns
    ///
    /// User 구조체의 새 인스턴스
    pub fn new(name: &str, email: &str) -> Self {
        User {
            name: name.to_string(),
            email: email.to_string(),
        }
    }
}

김개발 씨는 사용자 관리 기능을 완성했습니다. 하지만 기획팀에서 "다른 팀에서도 이 기능을 쓰고 싶은데, 어떻게 사용하면 되나요?"라고 물어왔습니다.

별도로 문서를 작성하려니 막막했습니다. 스크린샷도 찍어야 하고, 예제 코드도 작성해야 하고, 포맷도 맞춰야 합니다.

게다가 코드가 바뀌면 문서도 수정해야 합니다. 박시니어 씨가 웃으며 말했습니다.

"Rust는 코드 자체가 문서가 될 수 있어요. /// 주석을 사용해 보세요." 문서화 주석은 일반 주석과 무엇이 다를까요?

가장 큰 차이점은 자동 문서 생성입니다. cargo doc --open 명령어를 입력하면, Rust가 모든 문서화 주석을 수집해서 아름다운 HTML 웹사이트를 만들어줍니다.

마치 레고 블록을 조립하면 멋진 성이 완성되는 것과 같습니다. 위 코드를 자세히 보겠습니다.

User 구조체 위에 ///로 시작하는 주석이 있습니다. 이 주석에는 구조체의 설명뿐만 아니라 Examples 섹션도 있습니다.

여기에 작성한 코드는 실제로 테스트로 실행됩니다. 문서와 테스트를 동시에 작성하는 셈입니다.

필드 위에도 문서화 주석을 달 수 있습니다. name 필드 위에는 "사용자의 이름 (한글, 영문 모두 가능)"이라고 적었습니다.

이렇게 하면 생성된 문서에서 각 필드의 설명을 바로 확인할 수 있습니다. 함수에도 문서화 주석을 달 수 있습니다.

new 함수 위에는 Arguments와 Returns 섹션을 추가했습니다. 이 함수가 어떤 매개변수를 받고 어떤 값을 반환하는지 명확하게 설명합니다.

실무에서 이 기능은 정말 강력합니다. 예를 들어 팀에서 공통 라이브러리를 개발한다고 가정해봅시다.

각 함수와 구조체에 문서화 주석을 달아두면, 다른 팀원들은 별도의 위키나 문서 사이트를 찾아볼 필요 없이 cargo doc으로 생성된 문서만 보면 됩니다. 더 놀라운 점은 문서 내의 코드가 테스트로 실행된다는 것입니다.

Examples 섹션에 작성한 코드는 cargo test 명령어로 자동 테스트됩니다. 문서가 항상 최신 코드와 동기화되는 것을 보장하는 멋진 기능입니다.

김개발 씨는 기존 코드에 문서화 주석을 추가했습니다. 그리고 cargo doc --open 명령어를 실행했습니다.

브라우저에 자동으로 생성된 문서가 열렸고, 기획팀은 감탄했습니다. "와, 이렇게 깔끔한 문서가 자동으로 만들어지네요!"

실전 팁

💡 - Examples 섹션에 실행 가능한 코드를 작성하면 문서와 테스트를 동시에 해결합니다

  • cargo doc --open으로 생성된 문서를 바로 확인하세요

4. 모듈 문서화 주석

프로젝트 규모가 커지면서 여러 파일로 코드가 분리되었습니다. 김개발 씨는 각 파일이 무슨 역할을 하는지 한눈에 알 수 있게 정리하고 싶었습니다.

"파일 전체를 설명하는 주석은 없을까?"

모듈 문서화 주석//!로 작성합니다. 파일이나 모듈의 최상단에 위치하며, 전체 모듈에 대한 설명을 담습니다.

마치 책의 서문처럼, 이 모듈이 무엇을 담당하는지 설명합니다.

다음 코드를 살펴봅시다.

//! # 사용자 관리 모듈
//!
//! 이 모듈은 사용자 인증, 프로필 관리, 권한 처리를 담당합니다.
//!
//! ## 주요 기능
//!
//! - 사용자 가입 및 로그인
//! - 프로필 정보 수정
//! - 권한 레벨 관리
//!
//! ## 사용 예시
//!
//! ```rust
//! use user_management::{User, AuthLevel};
//!
//! let user = User::new("김개발", AuthLevel::Admin);
//! ```

pub struct User {
    pub name: String,
    pub auth_level: AuthLevel,
}

pub enum AuthLevel {
    Guest,
    Member,
    Admin,
}

김개발 씨의 프로젝트가 점점 커지고 있습니다. 처음에는 main.rs 파일 하나로 시작했지만, 이제는 user.rs, auth.rs, database.rs 등 여러 파일로 나뉘었습니다.

새로 합류한 팀원이 물었습니다. "user.rs 파일이 무슨 역할을 하는 건가요?" 김개발 씨는 매번 설명해야 했습니다.

"그 파일은 사용자 관련 기능을 담고 있어요. 로그인도 있고, 프로필 수정도 있고..." 박시니어 씨가 제안했습니다.

"파일 자체를 설명하는 주석을 달아보세요. //!를 사용하면 됩니다." //!///의 차이는 무엇일까요?

///는 바로 다음에 오는 항목(함수, 구조체 등)을 설명합니다. 반면 //!는 자신이 포함된 모듈이나 파일 전체를 설명합니다.

마치 책의 각 장을 설명하는 서문 같은 역할입니다. 위 코드를 보면 파일 최상단에 //!로 시작하는 주석이 있습니다.

여기서는 모듈의 전반적인 설명, 주요 기능 목록, 사용 예시를 제공합니다. 이렇게 작성해두면, 문서를 생성했을 때 모듈 페이지의 상단에 이 내용이 표시됩니다.

실무에서는 특히 라이브러리 개발 때 유용합니다. 사용자가 여러분의 라이브러리 문서를 열면, 가장 먼저 모듈 문서화 주석을 보게 됩니다.

"이 라이브러리가 무엇을 하는지, 어떻게 사용하는지"를 한눈에 파악할 수 있어야 합니다. 주요 기능을 목록으로 정리하는 것도 좋은 방법입니다.

위 코드에서는 "사용자 가입 및 로그인", "프로필 정보 수정", "권한 레벨 관리"를 명시했습니다. 이렇게 하면 문서를 읽는 사람이 "내가 원하는 기능이 여기 있는지"를 빠르게 확인할 수 있습니다.

사용 예시도 포함하는 것이 좋습니다. 실제 코드를 보여주면, 문서만 읽고도 바로 사용법을 익힐 수 있습니다.

마치 요리 레시피에 완성 사진이 있으면 더 이해하기 쉬운 것과 같습니다. 김개발 씨는 모든 주요 파일에 모듈 문서화 주석을 추가했습니다.

새로운 팀원이 합류했을 때, "문서부터 읽어보세요"라고 안내할 수 있게 되었습니다. 팀원은 혼자서도 프로젝트 구조를 파악할 수 있었습니다.

실전 팁

💡 - 모듈의 목적과 주요 기능을 목록으로 정리하세요

  • 간단한 사용 예시를 포함하면 이해도가 크게 높아집니다

5. 문서화 주석의 마크다운

"주석에도 포맷팅을 할 수 있나요?" 김개발 씨가 박시니어 씨에게 물었습니다. 문서가 단조로워서 가독성이 떨어졌기 때문입니다.

박시니어 씨가 미소 지으며 "마크다운을 사용할 수 있어요"라고 답했습니다.

Rust의 문서화 주석은 마크다운 문법을 완벽하게 지원합니다. 제목, 목록, 코드 블록, 링크, 굵은 글씨 등을 자유롭게 사용할 수 있습니다.

마치 블로그에 글을 작성하듯 풍부한 문서를 만들 수 있습니다.

다음 코드를 살펴봅시다.

/// 텍스트를 처리하는 유틸리티 함수들입니다.
///
/// # Features
///
/// - **Text Processing**: 문자열 가공 및 변환
/// - **Validation**: 입력값 검증
/// - **Formatting**: 다양한 포맷으로 변환
///
/// # Safety
///
/// 이 함수들은 패닉을 발생시키지 않습니다.
/// 모든 입력값에 대해 안전하게 처리됩니다.
///
/// # Panics
///
/// 입력이 `None`인 경우 패닉이 발생할 수 있습니다.
///
/// # Errors
///
/// `TextError` 타입의 에러를 반환할 수 있습니다.
///
/// # See Also
///
/// - [`format_text`](fn.format_text.html)
/// - [Rust Documentation](https://doc.rust-lang.org/)
pub fn process_text(input: Option<&str>) -> Result<String, TextError> {
    match input {
        Some(text) => Ok(text.to_uppercase()),
        None => Err(TextError::EmptyInput),
    }
}

pub enum TextError {
    EmptyInput,
}

김개발 씨는 문서화 주석을 열심히 작성하고 있었습니다. 하지만 생성된 문서를 보니 조금 밋밋해 보였습니다.

모든 내용이 평범한 텍스트로만 표시되니 중요한 부분이 눈에 잘 띄지 않았습니다. 박시니어 씨가 지나가다 말했습니다.

"김개발 씨, 마크다운 쓰세요. Rust 문서는 마크다운을 완벽하게 지원해요." 마크다운이 무엇일까요?

간단한 기호로 문서를 예쁘게 꾸밀 수 있는 문법입니다. #을 쓰면 제목이 되고, **로 감싸면 굵은 글씨가 됩니다.

마치 메모장에 적은 내용이 웹페이지로 변신하는 마법 같습니다. 위 코드를 보면 다양한 마크다운 요소를 사용했습니다.

# Features, # Safety 같은 제목은 문서에서 큰 글씨로 표시됩니다. - 기호로 목록을 만들었고, **Text Processing**처럼 굵은 글씨도 사용했습니다.

특히 유용한 것은 특수 섹션들입니다. Rust 문서에서는 # Safety, # Panics, # Errors, # Examples 같은 섹션을 관례적으로 사용합니다.

이 섹션들은 개발자들이 가장 궁금해하는 정보를 담습니다. # Safety는 안전과 관련된 주의사항을 적습니다.

이 함수가 unsafe 블록을 사용하는지, 어떤 조건에서 안전한지 등을 설명합니다. # Panics는 함수가 패닉을 일으킬 수 있는 상황을 적습니다.

호출하는 쪽에서 이를 대비할 수 있습니다. # Errors는 함수가 반환할 수 있는 에러 타입과 상황을 설명합니다.

에러 처리를 어떻게 해야 할지 미리 알 수 있습니다. # See Also는 관련 함수나 외부 문서의 링크를 제공합니다.

[format_text](fn.format_text.html) 같은 문법으로 다른 함수에 대한 링크를 걸 수 있습니다. 외부 웹사이트 링크도 가능합니다.

실무에서 이 기능을 잘 활용하면, 별도의 위키나 문서 사이트 없이도 훌륭한 기술 문서를 만들 수 있습니다. 특히 오픈소스 프로젝트에서는 이런 문서의 품질이 사용자 경험을 크게 좌우합니다.

김개발 씨는 마크다운을 활용해 문서를 풍성하게 만들었습니다. 이제 문서를 읽는 동료들이 "아, 이 부분이 중요하구나", "에러가 나면 이렇게 처리하면 되는구나"라고 쉽게 파악할 수 있게 되었습니다.

실전 팁

💡 - # Safety, # Panics, # Errors 섹션을 활용해 중요 정보를 강조하세요

  • 관련 함수나 외부 문서로 링크를 걸어 연결성을 높이세요

6. 문서 테스트의 힘

"문서에 작성한 예제 코드, 정말 작동하는 건가요?" 김개발 씨가 의문을 품었습니다. 문서에 예시를 적어놓았지만, 실제로 실행해보지 않아서 확신이 서지 않았던 것입니다.

박시니어 씨가 "테스트해 보세요"라고 말했습니다.

문서 테스트는 문서화 주석 내의 코드 블록을 자동으로 테스트하는 기능입니다. cargo test 명령어를 실행하면 문서 내의 모든 예제 코드가 실제로 컴파일되고 실행됩니다.

문서와 코드가 항상 일치하도록 보장합니다.

다음 코드를 살펴봅시다.

/// 두 수를 더하는 함수입니다.
///
/// # Examples
///
/// ```
/// use my_math::add;
///
/// assert_eq!(add(2, 3), 5);
/// assert_eq!(add(-1, 1), 0);
/// assert_eq!(add(0, 0), 0);
/// ```
///
/// # Panics
///
/// 오버플로우가 발생하면 패닉이 일어납니다.
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

/// 안전한 덧셈 함수입니다.
///
/// # Examples
///
/// ```
/// use my_math::checked_add;
///
/// assert_eq!(checked_add(2, 3), Some(5));
/// assert_eq!(checked_add(i32::MAX, 1), None);
/// ```
pub fn checked_add(a: i32, b: i32) -> Option<i32> {
    a.checked_add(b)
}

김개발 씨는 수학 라이브러리를 개발하고 있었습니다. 각 함수에 친절하게 예제 코드를 작성해 두었습니다.

하지만 시간이 지나면서 걱정이 생겼습니다. "나중에 함수를 수정하면 예제 코드도 바꿔야 하는데, 깜빡하면 어떡하지?" 이건 정말 중요한 문제입니다.

문서에 있는 예제 코드가 실제 함수와 맞지 않으면, 문서를 읽는 사람은 큰 혼란을 겪습니다. "문서대로 했는데 왜 안 되지?"라며 시간을 낭비하게 됩니다.

박시니어 씨가 해결책을 제시했습니다. "김개발 씨, cargo test 한번 실행해 보세요." 김개발 씨가 명령어를 입력했습니다.

놀랍게도 문서에 작성한 예제 코드들이 실제로 실행되었습니다. assert_eq!(add(2, 3), 5) 같은 코드가 테스트로 동작한 것입니다.

이것이 바로 문서 테스트의 마법입니다. Rust는 문서화 주석 내의 ```로 감싸인 코드 블록을 자동으로 테스트합니다.

일반 cargo test 명령어만으로 모든 문서 예제가 검증됩니다. 위 코드를 보면 두 함수가 있습니다.

add 함수는 일반 덧셈을 수행하고, checked_add 함수는 오버플로우를 안전하게 처리합니다. 각 함수의 Examples 섹션에 여러 테스트 케이스를 작성했습니다.

이제 함수를 수정하면 어떻게 될까요? 예를 들어 add 함수의 반환 타입을 i64로 바꾸면, cargo test를 실행할 때 문서 테스트가 실패합니다.

"문서의 예제 코드가 더 이상 유효하지 않습니다"라고 알려주는 것입니다. 개발자는 즉시 문서를 수정해야 함을 알게 됩니다.

실무에서 이 기능은 정말 귀중합니다. 특히 라이브러리를 개발할 때 더욱 그렇습니다.

사용자가 보게 될 문서의 예제 코드가 항상 작동함을 보장할 수 있습니다. "문서대로 하면 반드시 작동합니다"라는 신뢰를 줄 수 있는 것입니다.

더 나아가, 문서 테스트는 예제 코드를 작성하는 시점에 버그를 발견할 수도 있습니다. 예제 코드를 작성하다가 "어, 이 함수는 이런 입력을 처리 못하네?"라고 깨닫게 되는 경우도 많습니다.

김개발 씨는 이제 안심하고 문서를 작성합니다. cargo test만 실행하면 문서의 정확성까지 검증되니까요.

"문서와 코드가 서로를 감시하는 것 같아. 둘 중 하나라도 어긋나면 바로 알 수 있어!"

실전 팁

💡 - 문서에 예제 코드를 작성할 때 다양한 케이스를 포함하세요

  • cargo test를 정기적으로 실행해 문서와 코드의 일치를 확인하세요

7. 주석 스타일 가이드

팀이 커지면서 코드 리뷰 시간에 논쟁이 생겼습니다. "주석은 한 줄로 달아야 해요, 아니면 여러 줄로 달아야 해요?" 각자 다른 스타일로 주석을 작성하니 코드가 통일되지 않았던 것입니다.

주석 스타일 가이드는 팀 전체가 일관된 방식으로 주석을 작성하기 위한 규칙입니다. 언제 어떤 주석을 사용할지, 어떤 내용을 적을지 정해두면 코드의 가독성이 크게 향상됩니다.

다음 코드를 살펴봅시다.

// 좋은 예: 의도를 설명하는 주석
fn calculate_price(quantity: u32, unit_price: u32) -> u32 {
    // 대량 구매 할인 적용 (100개 이상 구매 시 10% 할인)
    let discount = if quantity >= 100 { 0.9 } else { 1.0 };

    (quantity as f64 * unit_price as f64 * discount) as u32
}

// 나쁜 예: 자명한 내용을 적은 주석
fn add_one(n: i32) -> i32 {
    // n에 1을 더해서 반환
    n + 1
}

// 좋은 예: 복잡한 로직을 설명하는 주석
fn validate_email(email: &str) -> bool {
    // RFC 5322 표준을 기반으로 한 간소화된 이메일 검증
    // 실무에서는 regex 크레이트 사용 권장
    email.contains('@') && email.contains('.')
}

/*
 * TODO: 성능 최적화 필요
 * 현재 O(n²) 알고리즘을 O(n log n)으로 개선 예정
 * 작성자: 김개발
 * 일자: 2024-01-15
 */
fn legacy_sort(arr: &mut [i32]) {
    // 구현 생략
}

김개발 씨가 속한 팀에 새로운 팀원 두 명이 합류했습니다. 코드 리뷰를 하던 중, 박시니어 씨가 고개를 갸웃했습니다.

"주석 스타일이 제각각이네요. 통일이 필요해 보입니다." 한 팀원은 모든 함수에 빽빽하게 주석을 달았습니다.

또 다른 팀원은 주석을 거의 작성하지 않았습니다. 어떤 주석은 도움이 되지만, 어떤 주석은 오히려 방해가 되었습니다.

팀 회의를 통해 주석 스타일 가이드를 만들기로 했습니다. 좋은 주석과 나쁜 주석의 차이를 명확히 하고, 팀 전체가 일관된 스타일을 유지하기로 했습니다.

가장 중요한 원칙은 "무엇을"이 아니라 "왜"를 적는 것입니다. 코드 자체가 무엇을 하는지는 이미 설명하고 있습니다.

주석은 "왜 이렇게 작성했는지"를 설명해야 합니다. 위 코드의 좋은 예를 보겠습니다.

calculate_price 함수의 주석은 "대량 구매 할인 적용"이라고 적혀 있습니다. 왜 0.9라는 숫자를 곱하는지 설명합니다.

반면 나쁜 예의 add_one 함수는 "n에 1을 더해서 반환"이라고 적혀 있습니다. 코드를 보면 이미 명확한 내용입니다.

이런 주석은 가독성을 떨어뜨립니다. 또 다른 원칙은 자명한 내용은 적지 않는 것입니다.

let x = 5; // x에 5를 대입 같은 주석은 아무 도움이 안 됩니다. 대신 복잡한 로직이나 특별한 이유가 있을 때만 주석을 작성합니다.

validate_email 함수의 주석을 보면 "RFC 5322 표준을 기반으로 한 간소화된 이메일 검증"이라고 적혀 있습니다. 이 검증 로직의 근거를 명확히 설명합니다.

또한 "실무에서는 regex 크레이트 사용 권장"이라고 개선점도 제시합니다. TODO 주석도 체계적으로 관리합니다.

위 코드에서는 TODO 주석에 작성자와 일자를 포함했습니다. 이렇게 하면 나중에 누가, 언제, 무엇을 계획했는지 추적할 수 있습니다.

실무에서는 팀마다 조금씩 다른 스타일 가이드를 가질 수 있습니다. 중요한 것은 일관성입니다.

한 팀원은 //만 쓰고, 다른 팀원은 /* */만 쓴다면 코드가 지저분해 보입니다. 모두가 같은 규칙을 따르면 코드가 깔끔해집니다.

김개발 씨의 팀은 스타일 가이드를 문서화했습니다. 새로운 팀원이 합류하면 이 가이드를 먼저 읽도록 안내합니다.

이제 모든 팀원이 일관된 스타일로 주석을 작성합니다.

실전 팁

💡 - "왜"에 집중하고 자명한 내용은 피하세요

  • TODO 주석에는 작성자와 일자를 포함해 관리하세요

8. 주석과 리팩토링

"이 함수, 주석이 너무 길어요. 함수 자체를 쪼개는 게 어떨까요?" 박시니어 씨의 코드 리뷰 피드백이었습니다.

김개발 씨는 주석으로 설명하려다 보니 함수가 길어졌던 것입니다.

주석과 리팩토링은 밀접한 관계가 있습니다. 주석이 너무 길어지면 그 자체가 코드를 개선해야 한다는 신호입니다.

함수를 작게 나누거나 변수명을 명확히 하면 주석이 필요 없어지는 경우도 많습니다.

다음 코드를 살펴봅시다.

// 리팩토링 전: 주석으로 설명이 필요한 긴 함수
fn process_order(order: &Order) -> Result<Receipt, Error> {
    // 재고 확인
    if order.quantity > get_stock(order.product_id) {
        return Err(Error::OutOfStock);
    }

    // 가격 계산 (기본 가격 + 옵션 가격 - 할인)
    let base_price = get_base_price(order.product_id);
    let option_price = calculate_option_price(&order.options);
    let discount = calculate_discount(order.user_id);
    let total = base_price + option_price - discount;

    // 결제 처리
    process_payment(order.user_id, total)?;

    // 영수증 생성
    Ok(Receipt { total, items: order.items.clone() })
}

// 리팩토링 후: 함수 분리로 주석 불필요
fn process_order(order: &Order) -> Result<Receipt, Error> {
    check_stock_availability(order)?;
    let total = calculate_total_price(order);
    process_payment(order.user_id, total)?;
    Ok(create_receipt(order, total))
}

fn check_stock_availability(order: &Order) -> Result<(), Error> {
    if order.quantity > get_stock(order.product_id) {
        Err(Error::OutOfStock)
    } else {
        Ok(())
    }
}

fn calculate_total_price(order: &Order) -> u32 {
    let base = get_base_price(order.product_id);
    let options = calculate_option_price(&order.options);
    let discount = calculate_discount(order.user_id);
    base + options - discount
}

김개발 씨는 주문 처리 시스템을 개발하고 있었습니다. 하나의 함수에서 재고 확인, 가격 계산, 결제 처리, 영수증 생성을 모두 처리했습니다.

각 단계를 설명하기 위해 주석을 많이 달았습니다. 코드 리뷰 시간에 박시니어 씨가 말했습니다.

"김개발 씨, 이 함수에 주석이 많은데, 혹시 함수를 쪼개볼 생각은 안 해봤어요?" 처음에는 이해하지 못했습니다. 주석을 잘 달았는데 왜 함수를 쪼개야 하지?

하지만 곧 깨달았습니다. 주석이 필요하다는 것은 코드가 스스로를 설명하지 못한다는 뜻입니다.

리팩토링 전 코드를 보겠습니다. process_order 함수가 모든 일을 처리합니다.

각 단계마다 주석이 있습니다. "재고 확인", "가격 계산", "결제 처리", "영수증 생성".

주석 덕분에 이해할 수 있지만, 함수 자체가 복잡해 보입니다. 리팩토링 후 코드를 보겠습니다.

process_order 함수가 훨씬 간결해졌습니다. 각 단계가 별도의 함수로 분리되었습니다.

check_stock_availability, calculate_total_price, create_receipt 같은 함수명이 이미 역할을 설명합니다. 주석이 필요 없습니다.

이것이 자기 설명적 코드의 힘입니다. 함수명과 변수명만으로도 코드가 무엇을 하는지 명확합니다.

마치 잘 쓰인 소설을 읽듯, 코드가 술술 읽힙니다. 물론 모든 주석을 없애라는 뜻은 아닙니다.

여전히 주석은 필요합니다. 하지만 "주석으로 설명해야겠다"는 생각이 들면 먼저 "코드를 더 명확하게 작성할 수 있을까?"를 고민해보세요.

실무에서는 이 원칙이 특히 중요합니다. 코드는 수시로 변경됩니다.

함수를 수정하면 주석도 업데이트해야 합니다. 하지만 함수명은 코드 그 자체이기 때문에 항상 최신 상태를 유지합니다.

함수명으로 의도를 전달하면 동기화 문제에서 자유로워집니다. 김개발 씨는 리팩토링을 통해 코드를 깔끔하게 만들었습니다.

이제 다른 팀원들이 코드를 읽을 때 주석을 찾을 필요가 없습니다. 함수명만 봐도 무슨 일을 하는지 명확합니다.

"주석을 줄였는데 오히려 코드가 더 읽기 쉬워졌어!"

실전 팁

💡 - 주석이 길어지면 함수 분리를 고려하세요

  • 함수명과 변수명으로 의도를 전달하면 유지보수가 쉬워집니다

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Rust#Comments#Documentation#DocComments#BestPractices

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스

Rust 댕글링 참조 방지하기 완벽 가이드

Rust의 소유권 시스템이 어떻게 댕글링 참조를 컴파일 타임에 방지하는지 알아봅니다. 메모리 안전성을 보장하는 Rust의 핵심 메커니즘을 초보자도 쉽게 이해할 수 있도록 풀어냅니다.

Premium

Rust 표현식과 구문 완벽 가이드

Rust에서 표현식과 구문의 차이를 명확히 이해하고, 이를 활용해 더 간결하고 안전한 코드를 작성하는 방법을 배워봅니다. 입문자가 가장 헷갈려하는 개념을 실무 예제와 함께 쉽게 풀어냅니다.

Premium

파일 입출력에서 with문 사용하기 완벽 가이드

Python에서 파일을 안전하게 다루는 with문의 모든 것을 알아봅니다. 파일 자동 닫기부터 예외 처리까지, 실무에서 반드시 알아야 할 핵심 개념을 이북처럼 술술 읽히는 스타일로 정리했습니다.

Premium

프롬프트 템플릿과 변수 완벽 가이드

AI 프롬프트를 효율적으로 관리하고 재사용하는 방법을 배웁니다. 템플릿 변수 정의부터 동적 프롬프트 생성, 버전 관리까지 실전 예제와 함께 설명합니다. 점프 투 자바 스타일로 술술 읽히는 이북 형식입니다.

Premium

포트폴리오 정리하기 완벽 가이드

초급 개발자를 위한 GitHub 포트폴리오 정리 가이드입니다. GitHub 계정 생성부터 프로젝트 구조화까지, 취업에 필요한 모든 것을 담았습니다. 실무 예제와 함께 단계별로 따라하면서 나만의 포트폴리오를 완성해보세요.

Premium