Rust에서 모듈과 경로를 다룰 때 가장 중요한 키워드 중 하나가 use다. use 키워드는 다른 모듈에 정의된 아이템(함수, 구조체, 열거형, 상수 등)을 현재 스코프로 가져와, 경로를 단축하거나 다시 내보낼(re-export) 수 있는 역할을 수행한다. 이를 통해 긴 경로를 반복해서 작성하지 않아도 되고 모듈 구조를 명확하게 유지할 수 있다.
Rust 모듈 시스템은 크레이트(crate)를 기준으로 경로를 해석한다. 크게 절대 경로와 상대 경로로 나뉘며, 절대 경로는 크레이트를 기준점으로 삼고 상대 경로는 현재 모듈을 기준점으로 삼는다. 절대 경로는 crate, super, self 같은 키워드나 최상위 모듈 이름으로 시작하는데, 주로 crate:: 또는 최상위 모듈 이름을 사용하여 표기한다. 상대 경로는 현재 위치한 모듈을 기준으로 하위 모듈을 탐색하거나 super 키워드로 상위 모듈을 탐색한다.
use 키워드는 일반적으로 모듈 스코프의 최상단에서 선언해 사용한다. 모듈 내에서 경로를 반복해서 써야 할 경우, use로 미리 불러와 단축된 이름(alias) 형태로 재사용할 수 있다. 예를 들어 아래 예시에서 network::server::run 함수를 자주 호출한다면 모듈 경로를 매번 network::server::run으로 쓰는 대신 use 문을 활용해 run으로만 호출할 수 있다.
mod network {
pub mod server {
pub fn run() {
println!("서버가 실행된다.");
}
}
}
fn main() {
use crate::network::server::run;
run();
}
절대 경로를 사용하는 방식과 함께, 상대 경로로도 use를 선언할 수 있다. 현재 모듈이 network라는 하위 모듈 안에 있다면 super로 상위 모듈을 가리키거나 self를 사용해 현재 모듈을 기준으로 가져올 수도 있다. 이때는 프로젝트 구조에서 모듈들이 실제로 어떻게 연결되어 있는지 정확히 파악해야 한다.
경로를 사용하는 또 다른 이유는 모듈 재노출(re-export) 기능이다. 모듈 내부에서 pub use를 사용해 가져온 아이템을 외부에 다시 공개할 수 있다. 이를 통해 라이브러리의 내부 구현 세부사항을 숨기면서도, 사용자(또는 다른 모듈)가 직접 접근해야 할 부분만 깔끔하게 노출할 수 있다.
mod network {
mod server_impl {
pub fn run_internal() {
println!("네트워크 서버 내부 로직이 실행된다.");
}
}
// 서버 로직을 재노출하여 network::server::run 으로 접근 가능
pub mod server {
pub use super::server_impl::run_internal as run;
}
}
fn main() {
// network::server::run 으로 불러오기
use crate::network::server::run;
run();
}
이처럼 pub use를 활용하면 모듈 내부 구현을 감추면서도 외부에 필요한 엔드포인트만 제공할 수 있다. 예시에서는 server_impl 모듈 내부 함수를 server 모듈에서 재노출하였기 때문에 server_impl이란 내부 이름을 외부에 공개하지 않아도 외부에서 run 함수를 쓸 수 있다.
use 선언부는 가급적 모듈의 최상단에 모아서 작성하는 것을 권장한다. 이렇게 하면 어떤 모듈과 어떤 아이템을 참조하고 있는지 명확히 파악할 수 있다. Rust 컴파일러는 사용되지 않는 use 선언을 경고하므로, 사용하지 않는 경로는 제거하는 것이 좋다. 또한, 같은 모듈 내부에서 여러 아이템을 가져올 때는 경로를 묶어서 가져올 수 있는 그룹화 문법이 지원된다.
위 코드에서는 std::io와 std::io::Write 두 경로를 한 번에 가져온다. self 키워드는 현재 모듈(std::io)의 별칭이 되어, io라는 이름으로 접근할 수 있게 만든다. 이 문법은 단순히 편의를 위해 제공되는 문법적 설탕(syntactic sugar)일 뿐, use가 원래 수행하는 역할은 동일하다.
정리하자면 use 키워드를 통해 모듈 경로를 효율적으로 단축해 사용할 수 있으며, pub use로 재노출을 통해 모듈 외부에서 접근 범위를 조절할 수도 있다. 경로와 모듈 구조를 잘 설계하고 적절히 use를 사용하는 것은 Rust 코드의 가독성과 유지보수성을 높이는 중요한 작업이다. 경로를 감추고 원하는 만큼만 공개하여 모듈 경계를 명확히 하는 것이 모듈 시스템의 핵심 목표다. 이러한 특징들을 깊이 이해하면, 큰 프로젝트에서도 모듈 간 의존성을 깔끔하게 유지할 수 있다.