7. 모듈

7.1. 모듈과 파일 시스템

  • 라이브러리를 생성하기 위해서는 cargo new에 반드시 --lib 옵션을 주어야 함.
  • 예전에는 옵션을 생략하면 라이브러리를 만들었지만 이제는 --bin이 디폴트.
cargo new communicator --lib
  • --lib는 다음과 같이 라이브러리의 템플릿슬 생성. 'src/lib.rs' 파일.
#[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); } }
💡
예전에는 it_works() 함수 몸통이 비어있었지만 지금은 assert_eq! 매크로가 들어가 있다. Rust에서 테스트를 이런 식으로 하는 거로군! 신기.
 

모듈 정의

  • mod는 모듈을 정의할 때 사용. { } 사이에 기술하는 내용은 모두 해당 모듈에 속함.
mod network { fn connect() { } } mod client { fn connect() { } }
  • connect 함수는 network라는 이름 공간에 있음. 이 공간 밮에서 connect를 참조할 때는 반드시 network::connect()로 참조해야 함. client::connect()와 완전 별개임.
  • 모듈 안에 다른 모듈이 포함될 수 있음
mod network { fn connect() { } mod client { fn connect() { } } }
  • 위의 경우 network::connect()network::client::connect()가 있는 것.
 

모듈을 다른 파일로 옮기기

  • 모듈은 얼마든지 계층적으로 구성 가능
mod client { fn connect() { } } mod network { fn connect() { } mod server { } }
 
  • client 모듈을 따로 파일로 분리하기
mod client; mod network { fn connect() { } mod server { fn connect() { } } }
  • mod client;의 의미는...
    • mod client { // contents of client.rs }
  • client.rs 파일을 이렇게 작성
fn connect() { }
  • Rust는 라이브러리에의 시작점을 src/lib.rs로 보고, 여기서부터 모듈을 찾음.
  • network 모듈도 분리해보자! lib.rs를 이렇게 짜고
mod client; mod network;
  • network.rs를 이렇게 짜면 됨.
fn connect() { } mod server { fn connect() { } }
  • 서브 모듈인 server는 여전히 mod 선언이 필요하다.
  • 서브 모듈을 풀어내려면 src/network 로 하위 폴더를 만든 다음 그 안에 mod.rs 파일을 만든다.
fn connect() { } mod server;
fn connect() { }
 
 

모듈 파일 시스템의 규칙

  • 만일 foo라는 이름의 모듈이 서브 모듈을 가지고 있지 않다면 foo.rs 라는 이름의 파일 내에 foo에 대한 선언을 집어넣어야 한다.
  • 만일 foo가 서브 모듈을 가지고 있다면 foo/mod.rs라는 이름의 파일에 foo에 대한 선언을 집어넣어야 한다.
 

7.2. pub으로 가시성 제어하기

 
mod outermost { pub fn middle_function() {} fn middle_secret_function() {} mod inside { pub fn inner_function() {} fn secret_function() {} } } fn try_me() { outermost::middle_function(); outermost::middle_secret_function(); outermost::inside::inner_function(); outermost::inside::secret_function(); }

비공개 규칙

  1. 만일 어떤 아이템이 공개라면, 이는 부모 모듈의 어디에서건 접근 가능하다.
  1. 만일 어떤 아이템이 비공개라면, 같은 파일 내부에 있는 부모 모듈 및 이 부모의 자식 모듈에서만 접근 가능하다.
 

7.3. use로 이름 가져오기

  • 이런 구조의 파일이 있다면....
pub mod a { pub mod series { pub mod of { pub fn nested_modules() {} } } } fn main() { a::series::of::nested_modules(); }
 

use를 이용한 간결한 가져오기

  • use 를 통해서 호출을 간단하게 만들 수 있다
pub mod a { pub mod series { pub mod of { pub fn nested_modules() {} } } } use a::series::of; fn main() { of::nested_modules(); }
  • a::series::of 를 쓰는 대신 그냥 of:: 라고만 할 수 있다.
  • use로 함수를 가져올 수도 있다!
pub mod a { pub mod series { pub mod of { pub fn nested_modules() {} } } } use a::series::of::nested_modules; fn main() { nested_modules(); }
  • 그냥 nested_modules() 라고만 쓰면 된다.