이전 글에서 러스트가 어떤 언어이며 C++와 어떤 점에서 다른지 간략히 살펴봤습니다. 이번 글에서는 러스트 개발을 보다 편리하게 만들어주는 표준 빌드 툴이자 패키지 매니저인 Cargo에 대해 알아봅니다. Cargo를 익히면 프로젝트 생성, 빌드, 실행, 라이브러리 의존성 관리 등이 훨씬 수월해집니다. 또한 기본적인 변수 선언, 함수 정의, 제어문 등을 살짝 맛보며 러스트 코드를 실제로 작성해봅시다.
Cargo란 무엇인가?
C++를 사용해보신 분이라면 빌드 도구로 CMake나 Meson, Bazel 등을 접했을 텐데요. 때로는 프로젝트 설정 파일이 복잡하거나 라이브러리를 링크하는 과정에서 어려움을 겪는 경우가 많습니다. 러스트는 이러한 문제를 해결하기 위해 Cargo라는 통합 빌드 & 패키지 관리 툴을 제공합니다.
- 프로젝트 생성: cargo new 명령어를 통해 순식간에 기본 디렉토리 구조와 Cargo.toml(프로젝트 설정 파일)을 갖춘 초기 프로젝트를 만들 수 있습니다.
- 빌드 & 실행: cargo build, cargo run 명령어 하나로 손쉽게 소스 코드를 빌드하고 실행할 수 있습니다.
- 테스트 & 문서화: cargo test 명령어로 테스트를 실행하고, cargo doc으로 문서를 생성할 수 있습니다.
- 의존성 관리: Cargo.toml 파일에 라이브러리(크레이트, crate) 의존성을 명시하면 Cargo가 자동으로 다운로드하고 빌드해줍니다.
C++에서 수많은 .cpp, .hpp 파일을 어떻게 링크하고 의존성 관리를 어떻게 할지 고민하는 대신, 러스트에서는 Cargo를 통해 훨씬 직관적인 경험을 할 수 있습니다.
프로젝트 생성하기
러스트가 설치되었다면(설치 방법은 이전 글 또는 아래 리소스 참고) 터미널(혹은 명령 프롬프트)에서 다음 명령어를 입력해보세요.
cargo new my_project
이렇게 하면 my_project라는 디렉토리가 생성되고, 그 안에 src 폴더와 Cargo.toml 파일이 생깁니다. src/main.rs 파일 안에는 기본적인 "Hello, world!" 코드가 들어있습니다. 이제 이 디렉토리로 들어가서 프로젝트를 빌드하고 실행해봅시다.
cd my_project
cargo run
결과:
Compiling my_project v0.1.0 (path/to/my_project)
Finished dev [unoptimized + debuginfo] target(s) in 0.65s
Running `target/debug/my_project`
Hello, world!
아주 간단하게 빌드와 실행이 이루어졌습니다.
C++와 비교하자면, 최소한의 CMakeLists.txt나 Makefile 없이도 프로젝트 관리가 가능하다는 점에서 상당히 편리합니다.
변수 선언과 불변성(Immutable by default)
이제 조금 더 러스트 코드를 다뤄보겠습니다. main.rs를 열어서 직접 코드를 수정해봅시다.
fn main() {
let x = 5;
println!("x의 값: {}", x);
// x = 10; // 이 줄은 컴파일 에러를 발생시킵니다!
}
러스트의 변수는 기본적으로 불변(immutable)입니다. 즉, let x = 5;로 선언하면 x는 재할당할 수 없습니다. C++에서 const int x = 5;를 선언한 것과 유사한 개념이 기본이라는 것이죠. 만약 값을 변경하고 싶다면 명시적으로 가변(mutable) 변수로 선언해야 합니다.
fn main() {
let mut y = 5;
println!("y의 값: {}", y);
y = 10;
println!("y의 새로운 값: {}", y);
}
mut 키워드가 붙은 변수는 재할당할 수 있습니다. C++에서 기본 변수는 가변적이며 const를 붙여야 불변이 되는 것과 달리, 러스트는 반대라는 점이 특이한 포인트입니다. 이는 코드의 안정성을 높이기 위한 러스트의 기본 철학 중 하나입니다.
함수 정의와 반환값
러스트의 함수는 fn 키워드로 정의하며, 매개변수와 반환 타입을 명확히 표기할 수 있습니다.
fn main() {
let result = add(3, 4);
println!("3 + 4 = {}", result);
}
fn add(a: i32, b: i32) -> i32 {
a + b // 세미콜론이 없는 마지막 표현식은 반환값으로 간주
}
여기서 C++와 다른 점은, 러스트는 함수 마지막에 return 키워드를 꼭 사용할 필요가 없습니다. 마지막 표현식의 값이 자동으로 반환됩니다(물론 return을 써도 되며, 명시적으로 반환할 수도 있습니다).
또한 타입 표기가 명확하고 컴파일러가 이를 엄격히 체크합니다. C++ 템플릿 기반으로 조금은 자유로운 추론과는 달리, 러스트는 타입에 대한 약속이 분명합니다.
제어문: if, loop, for, while
C++와 유사하게 if 문, for 문, while 문을 사용할 수 있습니다. 다만 러스트 if는 표현식(expression)이기 때문에 반환값으로 사용할 수도 있습니다.
fn main() {
let number = 10;
let result = if number > 5 { "크다" } else { "작다" };
println!("숫자는 {}", result);
for i in 0..3 {
println!("i: {}", i);
}
let mut count = 0;
while count < 3 {
println!("count: {}", count);
count += 1;
}
let mut loop_counter = 0;
let val = loop {
loop_counter += 1;
if loop_counter == 5 {
break loop_counter * 2; // 루프를 탈출하며 값을 반환
}
};
println!("val: {}", val);
}
여기서 for i in 0..3는 0부터 2까지 반복하는 구문이며, 0..3는 range(범위) 문법을 의미합니다. C++17 이후의 range-based for 문을 떠올리면 유사하게 느껴질 수 있습니다.
C++와의 비교 정리
- 불변 기본값: C++에서는 int x = 5; 후 x = 10;으로 쉽게 변경하지만, 러스트에선 let x = 5; 후 x = 10;은 불가능합니다. 변경 가능성을 명시적으로 밝히도록 하는 점이 러스트 코드를 더욱 신뢰성 있게 만듭니다.
- 명확한 타입 및 반환값 규칙: 러스트는 타입 추론도 강력하지만 기본적으로 타입을 명확히 하고, 함수 반환값을 마지막 표현식으로 다루는 등 코드 가독성과 안정성을 강조합니다.
- 빌드 시스템 통합: C++은 빌드 시스템, 패키지 관리자가 통합되어 있지 않고 선택지가 다양하지만, 러스트는 Cargo가 일체화를 제공, 프로젝트 관리를 일원화합니다.
앞으로의 학습 방향
이제 Cargo를 통해 프로젝트를 시작하고, 변수, 함수, 제어문 등을 간단히 살펴봤습니다. 다음 글에서는 러스트의 소유권(Ownership), 빌림(Borrowing), 라이프타임(Lifetime)이라는 핵심 개념을 더욱 자세히 파고들어 보겠습니다. 이는 C++에서 포인터를 다룰 때 발생하는 메모리 안전성 문제를 어떻게 러스트가 근본적으로 해결하고 있는지를 보여주는 흥미로운 주제입니다.
유용한 링크와 리소스
- Cargo 공식 문서: https://doc.rust-lang.org/cargo/
- 러스트 도구 체인 설치 안내(rustup): https://rustup.rs/
- Rust by Example (기본문법 예제집): https://doc.rust-lang.org/rust-by-example/
- C++ 프로젝트에서 러스트 사용하기(예시): https://cxx.rs/ (C++ 코드와 러스트 코드를 연동하는 프로젝트)
'개발 이야기 > Rust (러스트)' 카테고리의 다른 글
러스트 언어 입문 시리즈 - 5편: 구조체(Struct), 열거형(Enum), 패턴 매칭(Pattern Matching), 그리고 모듈(Module) 구조 (0) | 2024.12.10 |
---|---|
러스트 언어 입문 시리즈 - 4편: 컬렉션, 슬라이스, 이터레이터를 통한 실습 예제 (0) | 2024.12.09 |
러스트 언어 입문 시리즈 - 3편: 소유권(Ownership)과 빌림(Borrowing), 라이프타임(Lifetime)의 이해 (0) | 2024.12.08 |
러스트 언어 입문 시리즈 - 1편: 시작하기 전에 알아두면 좋은 것들 (0) | 2024.12.07 |
스크랩: 러스트(Rust) 언어 배우기 (0) | 2024.01.08 |