역사적으로 Rust는 대규모, 신뢰성 있는 시스템 프로그램을 작성하기 위한 언어로 설계되었습니다. 모듈 시스템은 네임스페이스를 엄격하게 구분하고, 코드를 격리시키며, 이름 충돌 없이 큰 프로젝트를 조직하기 위해 만들어졌습니다. 모듈은 코드를 구조화하고 구현 세부사항을 숨기며, 공개 API를 관리할 수 있게 합니다.
문제는 프로젝트가 성장함에 따라 구성 요소의 격리, 코드의 재사용 및 가시성 관리에 대한 질문이 생긴다는 것입니다. 오류는 종종 pub, pub(crate) 키워드를 잘못 사용하는 경우와 디렉토리 및 파일 구조가 없거나 잘못 구성된 경우에 발생합니다.
해결책: Rust에서 모듈은 mod 키워드를 사용하여 선언됩니다. 파일과 디렉토리는 네임스페이스를 구조화하여 계층성을 강조합니다. 기본적으로 모든 것이 비공개이며, pub, pub(crate), pub(super) 키워드를 사용하여 가시성을 관리할 수 있습니다. 내보내기, 별칭의 올바른 사용과 프로젝트를 모듈로 잘 나누는 것이 코드를 확장 가능하고 관리 가능하며 안전하게 만듭니다.
코드 예시:
// src/lib.rs mod network; pub use network::client::Client; // src/network/mod.rs pub mod client; // src/network/client.rs pub struct Client { pub name: String, }
주요 특징:
디렉토리 구조가 모듈 정의와 일치하지 않으면 무엇이 발생하나요?
코드가 컴파일되지 않습니다: Rust는 파일과 모듈 간의 엄격한 일치를 기대합니다 (예: mod foo가 선언되면, foo.rs 파일이나 foo/mod.rs 디렉토리가 존재해야 합니다).
pub(crate)는 외부 소비자로부터 구현을 숨기면서 동일한 크레이트 내 모든 모듈에서 접근 가능하게 할 수 있나요?
네, pub(crate)는 크레이트의 어떤 모듈에서도 요소를 보이게 하지만, 이 크레이트를 종속성으로 사용하는 외부 프로젝트에서는 보이지 않게 합니다.
공개 재수출(pub use) 없이 루트 파일에서 깊이 중첩된 모듈의 함수를 어떻게 가져오나요?
계층 구조를 통해 직접 참조하여 가져옵니다: crate::module::submodule::function. pub use 없이 이들은 크레이트 내에서만 접근할 수 있습니다.
네트워크 모듈은 모든 서버, 클라이언트, 프로토콜 파서 구성 요소를 하나의 파일 network.rs에 포함합니다. 모든 것이 pub로 선언되며, 테스트를 위해 내부 코드에 직접 연결됩니다. 시간이 지남에 따라 불필요한 결합성이 증가하고 공개 인터페이스와 구현을 분리하기 어려워집니다.
장점:
단점:
Network가 submodules: client, server, protocol로 나뉘어 있습니다. 오직 공개 인터페이스만 network에서 내보내며, API는 간결하고 세부 사항은 캡슐화됩니다. 각 모듈에 대한 테스트는 격리되어 있습니다.
장점:
단점: