Post

Rust examples 디렉토리로 똑똑하게 학습하기

Rust examples 디렉토리로 똑똑하게 학습하기

개요

Rust 프로젝트를 진행하다 보면, 특히 라이브러리를 개발하거나 여러 작은 기능을 테스트하고 싶을 때 코드를 어떻게 구성해야 할지 고민될 때가 있다. Cargo는 이러한 상황에 유용하게 사용할 수 있는 examples라는 특별한 디렉토리 기능을 지원한다. 이 글에서는 examples 디렉토리를 활용하여 학습 과정을 효율적으로 만들고, 코드 예제를 깔끔하게 관리하는 방법을 알아본다.


examples 디렉토리란?

Cargo는 프로젝트 루트에 위치한 examples 디렉토리를 특별하게 취급한다. 이 디렉토리 안에 있는 각 .rs 파일은 개별적인 실행 가능한 예제 프로그램으로 컴파일된다.
이 방식은 주로 라이브러리 개발자가 자신의 라이브러리 사용법을 보여주는 실제 동작 코드를 제공할 때 많이 사용된다. 하지만 학습 목적으로 여러 작은 프로그램을 만들고 실행해보며 특정 기능이나 개념을 익히고자 할 때도 매우 유용하다.

예를 들어, 다음과 같은 프로젝트 구조를 가질 수 있다:

1
2
3
4
5
6
7
8
my_rust_project/
├── Cargo.toml
├── src/
│   └── lib.rs       					// 주 라이브러리 코드 (또는 `main.rs`가 있을 수도 있음)
└── examples/
    ├── simple_cli.rs   			// 예제 프로그램 1 (main 함수 포함)
    └── data_processing.rs 		// 예제 프로그램 2 (main 함수 포함)
    └── using_lib_feature.rs	// 예제 프로그램 3 (라이브러리 기능 사용)

examples 디렉토리 설정 및 예제 작성

프로젝트 생성 및 Cargo.toml 설정:

새로운 Cargo 프로젝트를 생성하자.

1
2
$ cargo new my_rust_project
$ cd my_rust_project

Cargo.toml 파일은 다음과 같이 기본적으로 설정될 것이다.

1
2
3
4
5
6
7
[package]
name = "my_rust_project" # 이 이름은 예제에서 라이브러리를 참조할 때 사용된다
version = "0.1.0"
edition = "2021"

[dependencies]
# 필요한 의존성 추가

라이브러리 코드 작성 (선택 사항):

만약 examples에서 공통적으로 사용하거나 테스트하고 싶은 라이브러리 기능이 있다면 src/lib.rs 파일에 작성한다.

1
2
3
4
5
6
7
8
9
10
// src/lib.rs
pub fn project_info() -> String {
    String::from("This is a utility function from my_rust_project.")
}

pub mod utils {
    pub fn add(a: i32, b: i32) -> i32 {
        a + b
    }
}

examples 디렉토리 및 예제 파일 생성:

프로젝트 루트에 examples 디렉토리를 만들고, 그 안에 예제 .rs 파일을 작성한다. 각 파일은 main 함수를 가져야 한다.

examples/simple_cli.rs:

1
2
3
4
5
// examples/simple_cli.rs
fn main() {
    println!("This is a simple CLI example.");
    println!("Argument parsing would go here.");
}

examples/data_processing.rs:

1
2
3
4
5
6
7
8
9
10
// examples/data_processing.rs
fn main() {
    println!("Data processing example started...");
    let data = vec![10, 20, 30, 40, 50];
    let sum: i32 = data.iter().sum();
    let average = sum as f64 / data.len() as f64;
    println!("Data: {:?}", data);
    println!("Sum: {}", sum);
    println!("Average: {:.2}", average);
}

examples/using_lib_feature.rs:

src/lib.rs에 정의된 기능을 사용하는 예제이다. Cargo.toml에 정의된 package.name (여기서는 my_rust_project)을 사용하여 라이브러리 기능을 가져올 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// examples/using_lib_feature.rs
use my_rust_project::{project_info, utils}; // Cargo.toml의 name을 사용

fn main() {
    println!("--- Using Library Features Example ---");

    // src/lib.rs의 최상위 함수 호출
    let info = project_info();
    println!("Project Info: {}", info);

    // src/lib.rs의 모듈 내 함수 호출
    let num1 = 15;
    let num2 = 7;
    let sum_result = utils::add(num1, num2);
    println!("Using utils::add({}, {}): Result = {}", num1, num2, sum_result);

    println!("Example finished.");
}

예제 컴파일 및 실행 방법

examples 디렉토리의 특정 예제를 컴파일하고 실행하려면 cargo run --example <예제_파일_이름> 명령을 사용한다.
여기서 <예제_파일_이름>.rs 확장자를 제외한 파일 이름이다.

simple_cli 예제 컴파일 및 실행:

1
$ cargo run --example simple_cli

출력:

1
2
3
4
5
Compiling my_rust_project v0.1.0 (/path/to/my_rust_project)
	Finished dev [unoptimized + debuginfo] target(s) in 0.25s
		Running `target/debug/examples/simple_cli`
This is a simple CLI example.
Argument parsing would go here.

data_processing 예제 컴파일 및 실행:

1
$ cargo run --example data_processing

출력:

1
2
3
4
5
6
7
Compiling my_rust_project v0.1.0 (/path/to/my_rust_project)
	Finished dev [unoptimized + debuginfo] target(s) in 0.01s
		Running `target/debug/examples/data_processing`
Data processing example started...
Data: [10, 20, 30, 40, 50]
Sum: 150
Average: 30.00

using_lib_feature 예제 컴파일 및 실행:

1
$ cargo run --example using_lib_feature

출력:

1
2
3
4
5
6
7
Compiling my_rust_project v0.1.0 (/path/to/my_rust_project)
	Finished dev [unoptimized + debuginfo] target(s) in 0.30s
		Running `target/debug/examples/using_lib_feature`
--- Using Library Features Example ---
Project Info: This is a utility function from my_rust_project.
Using utils::add(15, 7): Result = 22
Example finished.

예제 빌드만 하기

실행하지 않고 빌드만 하려면 cargo build --example <예제_파일_이름> 명령을 사용한다.

1
$ cargo build --example simple_cli

빌드된 실행 파일은 target/debug/examples/ 디렉토리에 생성된다.
예를 들어, 위 명령을 실행하면 target/debug/examples/simple_cli (Windows에서는 target/debug/examples/simple_cli.exe) 실행 파일이 만들어진다.


examples 디렉토리 활용의 장점

  1. 개념별 코드 분리: 학습하는 각 개념이나 기능을 별도의 파일로 관리하여 코드베이스를 깨끗하게 유지할 수 있다.
  2. 빠른 실험 및 테스트: 작은 단위로 코드를 작성하고 즉시 실행해볼 수 있어, 특정 로직이나 API 사용법을 빠르게 익히고 검증하는 데 유리하다.
  3. 라이브러리 기능 연동: src/lib.rs 등에 정의된 공통 라이브러리 기능을 예제에서 쉽게 가져와 사용할 수 있다.
  4. 독립적인 실행 환경: 각 예제는 독립된 프로그램으로 실행되므로, 하나의 큰 main.rs 파일에서 코드를 주석 처리하거나 수정하며 테스트하는 것보다 훨씬 관리하기 편하다.
  5. 실제 프로젝트 구조 경험: 많은 실제 Rust 라이브러리들이 examples 디렉토리를 통해 사용 예시를 제공하므로, 이러한 구조에 익숙해지는 것은 실무 프로젝트를 이해하는 데 도움이 된다.

examples vs src/main.rs

  • src/main.rs: 프로젝트의 주 실행 파일을 정의한다. cargo run을 옵션 없이 실행하면 src/main.rs가 컴파일되고 실행된다. 하나의 주된 애플리케이션을 개발할 때 사용한다.
  • examples/*.rs: 여러 개의 부가적인 실행 파일을 정의한다. 각각은 독립적이며, 라이브러리의 특정 기능 사용 예시나 작은 유틸리티 등을 만들 때 유용하다. cargo run --example <name>으로 특정 예제를 지정하여 실행한다.

프로젝트에 src/main.rsexamples 디렉토리가 모두 존재할 수 있으며, 이들은 서로 다른 목적을 가진 실행 파일들을 제공한다.


결론

Rust의 examples 디렉토리는 단순한 코드 예시 제공을 넘어, 학습 과정을 체계적이고 효율적으로 만들어주는 강력한 도구이다.
여러 작은 아이디어를 실험하거나, 라이브러리의 다양한 기능을 테스트하거나, 특정 개념을 집중적으로 학습하고자 할 때 examples 디렉토리를 적극 활용해보자.
깔끔하게 정리된 코드와 함께 Rust 학습 경험이 한층 더 즐거워질 것이다.

This post is licensed under CC BY 4.0 by the author.