Rust Defining Modules to Control Scope and Privacy (Cheat Sheet)

고승우·2023년 7월 10일
0

Rust

목록 보기
2/16
post-thumbnail

Modules Cheat Sheet

  • Crate root: crate를 컴파일할 때 crate root file을 맨 처음 확인한다. library crate은 src/lib.rs을, binary crate은 src/main.rs을 crate root file로 인식한다.

  • Declaring modules: crate root file에서 새로운 modules를 선언할 수 있다. 가령 너가 "garden"이라는 모듈을 mod garden;을 통해 선언한다면, 컴파일러는 아래에서 module의 코드를 찾을 것이다

    • Inline, mod garden 뒤의 semicolon(;)을 대체한 중괄호 내부
    • src/garden.rs 파일
    • _src/garden/mod.rs 파일
  • Declaring submodules: crate root가 아닌 다른 모든 파일에서 submodule을 선언할 수 있다. 예를 들어 src/garden.rsmod vegetables을 declare한 경우, compiler는 아래에 있는 parent module의 이름을 가진 directory에서 submodule의 코드를 찾을 것이다.

    • Inline, mod vegetables 뒤의 semicolon(;)을 대체한 중괄호 내부
    • src/garden/vegetables.rs 파일
    • _src/garden/vegetables/mod.rs 파일
  • Paths to code in modules: module이 crate의 일부가 된 순간, privacy rule이 허락하는 한 같은 crate 내 어느 곳에서도 해당 module의 코드를 참조할 수가 있다. 예를 들어 garden vegetables module 안에 있는 Asparagus type은 crage::garden::vegetables::Asparagus에서 찾을 수 있다.

  • Private vs public: module 내부에 있는 code는 기본적으로 parent moudle로 부터 private하다. module을 public하게 만들기 위해선 mod 대신 pub mod를 선언해야 한다. public module 내의 item을 public하게 만들기 위해선, 선언 전에 pub를 사용해야 한다.

  • The use Keyword: use keyword는 long path의 shortcuts(바로가기)를 만들어준다. 예를 들어 모든 scope에서 참조할 수 있는 crate::garden::vegetables::Asparagususe 키워드를 통해 shortcut을 만든다면 Asparagus만으로 사용할 수 있다.

backyard
├── Cargo.lock
├── Cargo.toml
└── src
    ├── garden
    │   └── vegetables.rs
    ├── garden.rs
    └── main.rs
use crate::garden::vegetables::Asparagus;

pub mod garden;

fn main() {
    let plant = Asparagus {};
    println!("I'm growing {:?}!", plant);
}

pub mod garden은 compiler에게 src/garden.rs 에서 볼 수 있는 code를 include 하란 의미다.

Filename: src/garden.rs

pub mod vegetables;

여기에서 pub mod vegetables;src/garden/vegetables.rs 도 include 해달라는 의미이고 코드는 아래와 같다

#[derive(Debug)]
pub struct Asparagus {}

Module을 활용해서 코드를 재사용하기 쉽게 하고 가독성을 높일 수 있다. 또한, privacy를 컨트롤하여 external(외부) 코드가 접근할 수 있도록 할 지 정할 수 있다.

예를 들어, 레스토랑의 기능을 제공하는 library crate를 만들어 보자. restaurant라는 library를 cargo new restaurant --lib를 통해 만들고 아래 코드를 입력해보자.

mod front_of_house {
    mod hosting {
        fn add_to_waitlist() {}

        fn seat_at_table() {}
    }

    mod serving {
        fn take_order() {}

        fn serve_order() {}

        fn take_payment() {}
    }
}

우리는 mod keyword로 front_of_house라는 module을 만들고, 모듈 내부에 hostingserving이라는 다른 module을 넣었다. 이러한 구조를 설계함으로써 코드를 사용하는 프로그래머들은 따로 definition을 읽지 않아도 보다 쉽게 코드를 이해할 수 있다.

crate
 └── front_of_house
     ├── hosting
     │   ├── add_to_waitlist
     │   └── seat_at_table
     └── serving
         ├── take_order
         ├── serve_order
         └── take_payment
profile
٩( ᐛ )و 

0개의 댓글