💻 프로그래밍

보로우 체커

Borrow Checker

Rust 컴파일러의 핵심 기능. 소유권과 빌림 규칙을 검사하여 메모리 안전성 보장.

📖 상세 설명

보로우 체커(Borrow Checker)는 Rust 컴파일러의 핵심 구성 요소로, 소유권과 빌림 규칙을 컴파일 시점에 검증합니다. 이를 통해 런타임 오버헤드 없이 메모리 안전성과 데이터 레이스 방지를 보장합니다.

보로우 체커가 강제하는 핵심 규칙은 다음과 같습니다: 어떤 시점에든 하나의 가변 참조(&mut)만 존재하거나, 여러 개의 불변 참조(&)만 존재할 수 있습니다. 가변 참조와 불변 참조는 동시에 존재할 수 없습니다.

이 규칙은 데이터 레이스를 컴파일 시점에 방지합니다. 여러 스레드가 같은 데이터에 접근할 때, 적어도 하나가 쓰기를 하면 데이터 레이스가 발생할 수 있는데, Rust의 타입 시스템이 이를 원천적으로 차단합니다.

보로우 체커는 처음에는 제약적으로 느껴질 수 있지만, 익숙해지면 더 안전하고 명확한 코드를 작성하게 됩니다. Rust의 NLL(Non-Lexical Lifetimes) 도입으로 보로우 체커가 더 스마트해져서 이전보다 많은 패턴이 허용됩니다.

💻 코드 예제

Rust
fn main() {
    // 불변 빌림: 여러 개 가능
    let s = String::from("hello");
    let r1 = &s;
    let r2 = &s;
    println!("{}, {}", r1, r2);  // OK

    // 가변 빌림: 하나만 가능
    let mut s = String::from("hello");
    let r1 = &mut s;
    // let r2 = &mut s;  // 에러! 이미 가변 빌림 존재
    r1.push_str(" world");
    println!("{}", r1);

    // 불변 + 가변 동시 불가
    let mut s = String::from("hello");
    let r1 = &s;  // 불변 빌림
    // let r2 = &mut s;  // 에러! 불변 빌림이 아직 사용 중
    println!("{}", r1);  // r1 사용 종료

    // NLL: 사용 범위가 끝나면 새 빌림 가능
    let r2 = &mut s;  // OK! r1은 더 이상 사용되지 않음
    r2.push_str("!");
    println!("{}", r2);

    // 댕글링 참조 방지
    // fn dangle() -> &String {
    //     let s = String::from("hello");
    //     &s  // 에러! s는 함수 종료 시 해제됨
    // }

    // 올바른 방법: 소유권 이동
    fn no_dangle() -> String {
        let s = String::from("hello");
        s  // 소유권 이동
    }
}

🗣️ 실무 대화 예시

신입 개발자
"보로우 체커 에러 때문에 코드가 컴파일이 안 돼요. 너무 제약이 심한 것 같아요."
시니어 개발자
"처음엔 그렇게 느껴지죠. 하지만 보로우 체커가 잡는 에러는 다른 언어에서 런타임에 발생하는 심각한 버그예요. 컴파일러와 싸우는 게 아니라 협력한다고 생각하세요."
신입 개발자
"패턴을 좀 알려주실 수 있나요?"
면접관
"Rust의 보로우 체커가 해결하는 문제가 무엇인가요?"
지원자
"메모리 안전성 문제를 컴파일 시점에 해결합니다. 댕글링 포인터, 이중 해제, 데이터 레이스 같은 버그를 런타임 오버헤드 없이 방지합니다."
면접관
"RefCell과 Mutex는 왜 필요한가요?"
지원자
"보로우 규칙을 런타임으로 미루기 위해서입니다. 컴파일러가 안전성을 증명할 수 없는 경우에 내부 가변성 패턴으로 빌림 검사를 런타임에 수행합니다."
리뷰어
"여기서 clone()을 많이 쓰고 있네요. 빌림으로 해결할 수 있는 부분이 많아 보여요."
작성자
"보로우 체커 에러를 피하려고 clone을 썼는데, 성능 이슈가 있을까요?"
리뷰어
"String 같은 큰 데이터를 불필요하게 복사하면 성능이 떨어져요. 함수 시그니처를 &str로 바꾸면 빌림으로 해결됩니다."

⚠️ 주의사항

🔗 관련 용어

📚 더 배우기