💻 프로그래밍

Rust

Rust Language

메모리 안전성과 성능을 보장하는 시스템 프로그래밍 언어. 소유권 시스템으로 GC 없이 메모리 관리.

📖 상세 설명

Rust는 메모리 안전성과 높은 성능을 동시에 제공하는 시스템 프로그래밍 언어입니다. C/C++와 동등한 성능을 내면서도 컴파일 타임에 메모리 관련 버그를 방지할 수 있어, "안전한 시스템 프로그래밍"이라는 새로운 패러다임을 제시했습니다. 가비지 컬렉터 없이도 메모리 누수, 널 포인터 역참조, 데이터 레이스 같은 문제를 원천적으로 차단합니다.

Rust는 2010년 Mozilla의 Graydon Hoare가 개인 프로젝트로 시작했으며, 2015년 1.0 버전이 공식 출시되었습니다. Mozilla의 Firefox 브라우저 엔진인 Servo 프로젝트에서 Rust가 실제로 사용되면서 검증되었고, 이후 Stack Overflow 개발자 설문조사에서 7년 연속 "가장 사랑받는 언어" 1위를 차지할 정도로 개발자들의 큰 호응을 얻었습니다.

Rust의 핵심 특징은 소유권(Ownership), 빌림(Borrowing), 수명(Lifetime) 시스템입니다. 모든 값은 하나의 소유자만 가지며, 소유자가 스코프를 벗어나면 자동으로 메모리가 해제됩니다. 참조를 빌릴 때는 불변 참조는 여러 개, 가변 참조는 하나만 가능한 규칙이 적용됩니다. 또한 Zero-cost abstraction 원칙으로 고수준 추상화가 런타임 오버헤드 없이 동작합니다.

실무에서 Rust는 시스템 프로그래밍(OS, 드라이버, 임베디드), WebAssembly 개발, 고성능 CLI 도구에 널리 사용됩니다. Ripgrep, exa, bat 같은 CLI 도구, Deno와 SWC 같은 JavaScript 생태계 도구, 그리고 Cloudflare, Discord, Dropbox 등의 인프라에서 Rust가 채택되고 있습니다. Linux 커널에도 Rust 지원이 공식 추가되었습니다.

💻 코드 예제

// 1. 변수와 타입
fn main() {
    // 불변 변수 (기본값)
    let name: &str = "Rust";
    let year: u32 = 2015;

    // 가변 변수
    let mut count = 0;
    count += 1;

    // 구조체 정의
    struct User {
        username: String,
        email: String,
        active: bool,
    }

    let user = User {
        username: String::from("rustacean"),
        email: String::from("rust@example.com"),
        active: true,
    };

    // 열거형 (Enum)
    enum Message {
        Quit,
        Move { x: i32, y: i32 },
        Write(String),
    }

    // 패턴 매칭
    let msg = Message::Move { x: 10, y: 20 };
    match msg {
        Message::Quit => println!("종료"),
        Message::Move { x, y } => println!("이동: ({}, {})", x, y),
        Message::Write(text) => println!("메시지: {}", text),
    }

    println!("{} 언어, {}년 출시", name, year);
}

🗣️ 실무에서 이렇게 말하세요

💬 회의에서 - Rust 도입 검토
"이번 고성능 파싱 모듈은 Rust로 개발하는 것을 제안합니다. C++과 동등한 성능을 내면서도 메모리 안전성이 컴파일 타임에 보장되어, 프로덕션에서 발생하는 세그폴트나 메모리 누수 버그를 원천 차단할 수 있습니다. 학습 곡선이 있지만, 장기적으로 디버깅 시간을 크게 줄일 수 있어요."
💬 면접에서 - Ownership 설명
"Rust의 소유권 시스템은 세 가지 규칙으로 동작합니다. 첫째, 모든 값은 하나의 소유자만 가집니다. 둘째, 소유자가 스코프를 벗어나면 값이 자동으로 drop됩니다. 셋째, 참조를 빌릴 때 불변 참조는 여러 개 가능하지만, 가변 참조는 하나만 존재할 수 있습니다. 이 규칙들이 컴파일 타임에 강제되어 데이터 레이스를 방지합니다."
💬 코드 리뷰에서 - 에러 핸들링
"이 함수에서 unwrap()을 많이 쓰고 있는데, 프로덕션 코드에서는 위험해요. None이나 Err가 들어오면 패닉이 발생합니다. match로 명시적으로 처리하거나, ? 연산자로 에러를 호출자에게 전파하세요. expect()를 쓰더라도 의미 있는 메시지를 넣어서 디버깅을 쉽게 해주세요. anyhow나 thiserror 크레이트로 에러 타입을 체계화하면 더 좋습니다."

⚠️ 흔한 실수 & 주의사항

📚
학습 곡선이 가파름

소유권, 수명(Lifetime), 트레이트 등 Rust 특유의 개념을 이해하는 데 시간이 필요합니다. "Fighting the borrow checker"라는 말이 있을 정도로 초기에 컴파일러와 씨름하게 됩니다. 하지만 일단 익숙해지면 컴파일되는 코드는 거의 안전하다는 확신을 얻습니다.

🔒
Borrow Checker 이해하기

가변 참조와 불변 참조를 동시에 사용하거나, 댕글링 참조를 만들면 컴파일이 거부됩니다. `Rc>`나 `Arc>` 같은 스마트 포인터를 언제 사용해야 하는지 파악하세요. 때로는 코드 구조 자체를 바꿔야 빌림 검사기를 만족시킬 수 있습니다.

⏱️
컴파일 시간이 길 수 있음

복잡한 프로젝트는 컴파일에 수 분이 걸릴 수 있습니다. `cargo check`로 빠르게 문법 검사만 하거나, incremental compilation을 활용하세요. sccache를 사용하면 빌드 캐시로 재컴파일 시간을 줄일 수 있습니다.

🔗 관련 용어

📚 더 배우기