Rust 모듈
지금까지의 예제는 모두 main.rs 파일 하나에 들어 있었어요. 작은 프로그램이라면 그걸로 충분하지만, 실제 프로젝트에서는 코드를 의미 있는 덩어리로 나눠요. 이때 쓰는 Rust의 도구가 바로 모듈 시스템(module system), 즉 mod, pub, use예요.
모듈 정의하기
섹션 제목: “모듈 정의하기”모듈은 서로 관련된 코드를 하나로 묶어 주는, 이름이 붙은 블록이에요.
mod math { pub fn add(a: i32, b: i32) -> i32 { a + b }}
fn main() { let sum = math::add(2, 3); println!("{sum}");}실행 결과:
5여기서 두 가지를 눈여겨보세요. 함수를 부를 때 math::add(...)처럼 모듈 이름을 경로로 붙여서 불러요. 그리고 함수에 pub이 붙어 있어요. pub이 없으면 모듈 바깥에서는 이 함수에 접근할 수 없어요.
기본은 모두 비공개
섹션 제목: “기본은 모두 비공개”처음 보면 꽤 놀라는 부분이라 따로 짚고 넘어갈게요. 모듈 안의 내용은 기본적으로 비공개(private)예요. 위 예제에서 pub을 지우면 컴파일되지 않아요.
mod math { fn add(a: i32, b: i32) -> i32 { // `pub`이 없음 a + b }}
fn main() { let sum = math::add(2, 3); // ❌ 에러: function `add` is private println!("{sum}");}모듈 바깥에서 쓰게 하고 싶은 것에는 하나하나 직접 pub을 붙여야 해요. 일부러 이렇게 만든 거예요. 덕분에 모듈은 내부에서만 쓰는 도우미 함수는 숨기고, 공개 API로 내놓을 부분만 보여 줄 수 있어요.
중첩 모듈
섹션 제목: “중첩 모듈”모듈 안에 다른 모듈을 넣을 수도 있어요. 큰 프로젝트는 이런 식으로 나무 같은 구조를 만들어요.
mod shapes { pub mod circle { pub fn area(radius: f64) -> f64 { 3.14159 * radius * radius } }}
fn main() { let area = shapes::circle::area(2.0); println!("{area}");}use로 긴 경로 줄이기
섹션 제목: “use로 긴 경로 줄이기”매번 shapes::circle::area(...)라고 쓰다 보면 금방 지쳐요. use는 경로를 스코프 안으로 가져와서 짧게 부를 수 있게 해 줘요.
mod shapes { pub mod circle { pub fn area(radius: f64) -> f64 { 3.14159 * radius * radius } }}
use shapes::circle;
fn main() { let area = circle::area(2.0); // shapes::circle::area보다 짧아요 println!("{area}");}사실 use는 이미 써 봤어요. HashMap 페이지에서 본 use std::collections::HashMap;이 바로 같은 키워드예요.
모듈을 여러 파일로 나누기
섹션 제목: “모듈을 여러 파일로 나누기”위의 예제들은 모두 파일 하나에 들어 있어요. Rust Playground에서는 그렇게 해야 하거든요. 하지만 내 컴퓨터에서 실제 프로젝트를 만들 때는 보통 모듈마다 파일을 따로 둬요. math 모듈이 있는 프로젝트라면 대개 이런 모양이에요.
src/├── main.rs└── math.rsmod math; // Rust에게 "이 모듈의 코드는 math.rs에서 찾아"라고 알려 줘요
fn main() { let sum = math::add(2, 3); println!("{sum}");}pub fn add(a: i32, b: i32) -> i32 { a + b}본문 없이 세미콜론으로 끝나는 mod math;는 같은 폴더의 math.rs에서 모듈 내용을 불러오라는 뜻이에요. 프로젝트가 파일 하나를 넘어서기 시작하면 바로 이 방식을 쓰게 될 거예요.
연습 문제
섹션 제목: “연습 문제”1. 온도 변환 모듈
섹션 제목: “1. 온도 변환 모듈”convert라는 모듈을 만들고, 그 안에 공개 함수 두 개를 넣어 보세요. c_to_f(섭씨를 화씨로)와 f_to_c(그 반대)예요. main에서 100°C는 212°F와 212°F는 100°C를 출력하세요.
힌트: 공식은 c * 9.0 / 5.0 + 32.0과 (f - 32.0) * 5.0 / 9.0이에요. pub을 잊지 말고, convert::c_to_f(100.0)처럼 모듈 이름을 붙여서 함수를 부르세요.
정답 보기
mod convert { pub fn c_to_f(c: f64) -> f64 { c * 9.0 / 5.0 + 32.0 }
pub fn f_to_c(f: f64) -> f64 { (f - 32.0) * 5.0 / 9.0 }}
fn main() { println!("100°C는 {}°F", convert::c_to_f(100.0)); println!("212°F는 {}°C", convert::f_to_c(212.0));}실행 결과:
100°C는 212°F212°F는 100°C두 함수 모두 pub이라서, 모듈 바깥에 있는 main에서 부를 수 있어요. pub 하나를 지워 보면 컴파일러가 그 함수는 비공개라고 알려 줄 거예요.
2. 비공개 도우미 함수
섹션 제목: “2. 비공개 도우미 함수”중첩 모듈 school::grades를 만들고, 그 안에 공개 함수 letter(score: u32) -> char를 넣으세요. 90점 이상이면 'A', 80점 이상이면 'B', 그 밖에는 'C'를 돌려줘요. grades 안에는 letter가 사용하는 비공개 도우미 함수 is_at_least(score: u32, min: u32) -> bool도 만드세요. use로 school::grades를 스코프로 가져온 다음, 95, 85, 70점의 등급을 출력하세요.
힌트: school 안의 mod grades와 fn letter에는 둘 다 pub이 필요하지만, is_at_least에는 붙이면 안 돼요. 같은 모듈 안의 코드는 비공개 함수를 언제든 부를 수 있어요.
정답 보기
mod school { pub mod grades { pub fn letter(score: u32) -> char { if is_at_least(score, 90) { 'A' } else if is_at_least(score, 80) { 'B' } else { 'C' } }
// 비공개: `grades` 안의 코드만 부를 수 있어요 fn is_at_least(score: u32, min: u32) -> bool { score >= min } }}
use school::grades;
fn main() { for score in [95, 85, 70] { println!("{score} -> {}", grades::letter(score)); }}실행 결과:
95 -> A85 -> B70 -> Cletter와 is_at_least는 같은 모듈에 있으니 letter에서 is_at_least를 부를 수 있어요. 하지만 main에서 grades::is_at_least(95, 90)을 부르면 “function is_at_least is private” 에러가 나요. 바로 이게 핵심이에요. 모듈은 작은 공개 API만 보여 주고, 도우미 함수는 안에 감춰 둬요.
mod 이름 { ... }은 관련된 코드를 이름 붙은 모듈로 묶어요.- 모듈 안의 모든 것은 기본적으로 비공개예요. 모듈 바깥에 보여 주려면
pub을 붙이세요. use는 경로를 스코프로 가져와서, 매번 전체 경로를 쓰지 않아도 되게 해 줘요.- 여러 파일로 된 프로젝트에서는 본문 없는
mod 이름;이 같은 이름의 파일에서 모듈 코드를 불러와요. - 모듈 안의 코드는 그 모듈의 비공개 항목을 언제든 쓸 수 있어요. 그러니 도우미 함수는 비공개로 두고, 바깥에서 꼭 필요한 것만 공개하세요.
이해도 점검
섹션 제목: “이해도 점검”이해도 점검
1. mod 안의 항목은 기본적으로 공개일까요, 비공개일까요?
2. 모듈 코드를 직접 쓰지 않고 math.rs에서 불러오게 하려면 어떻게 써야 할까요?
점수: 0 / 2
더 알아보기
섹션 제목: “더 알아보기”- 커져 가는 프로젝트를 패키지, 크레이트, 모듈로 관리하기 — The Rust Programming Language 한국어판: 패키지, 크레이트, 모듈이 무엇이고 어떻게 맞물리는지 설명하는 공식 문서의 장이에요.
- 모듈을 정의하여 스코프 및 공개 여부 제어하기 — The Rust Programming Language 한국어판: 모듈 트리의 구체적인 예와, 규칙을 한눈에 정리한 요약표가 있어요.
- 별개의 파일로 모듈 분리하기 — The Rust Programming Language 한국어판: 중첩 모듈을 위한 폴더 구성까지 포함해서, 여러 파일로 나누는 방법을 더 자세히 다뤄요.
- Modules — Rust by Example (영어): 가시성,
use,super,self를 직접 실행해 볼 수 있는 예제예요. - Visibility and privacy — The Rust Reference (영어): “내 크레이트 안에서만 공개”를 뜻하는
pub(crate)까지 포함한 정확한 규칙이에요.