타나기
타나기 월드
타나기
전체 방문자
오늘
어제
  • 분류 전체보기 (90)
    • ⚙️ Rust (20)
      • 👀 Tutorial (20)
    • 🗿 Embedded (11)
      • 🐧 OS for ARM (11)
    • 💻 Study (37)
      • 🧩 알고리즘 (37)
    • 🏄🏽‍♂️ Life (21)
      • 🍚 타나구루망 (20)
      • 💡 Light (1)

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
타나기

타나기 월드

⚙️ Rust/👀 Tutorial

[Rust / 튜토리얼] 17. 러스트의 모듈 (mod)

2022. 6. 13. 21:32

mod와 파일 시스템

지금까지 진행하며 작성했던 작은 테스트 코드들은 모듈화를 할 필요가 없었다. 하지만 대규모의 프로젝트를 진행 한다고 생각 해 보자. 지금처럼 하나의 main.rs에 모든 코드를 때려 박을 순 없을 것이다. 코드의 유지보수 및 최적화 관점에서 모듈화는 중요한 요소이다. 이번 글에서는 지금까지 진행했던 binary crate에서 나아가 library crate를 생성하고 다루어 보자.

 

앞에서 주저리주저리 설명 했지만, 실제로 만드는 법은 엄청 간단하다. binary crate 처럼 library crate 역시 cargo를 사용한다. 거기서 옵션만 --bin 에서 --lib로 변경해 주면 된다. 그럼, 라이브러리 이름을communicator로 해서 생성해 보자.

MacBook-Pro rust % cargo new communicator --lib
     Created library `communicator` package
MacBook-Pro rust % cd communicator 
MacBook-Pro communicator % 

단어 몇개를 입력 하는 것 만으로 간단하게 라이브러리가 생성이 되었다. 이렇게 생성된 라이브러리 프로젝트는 바이너리 프로젝트와 다른 점이 한가지 있는데, main.rs 가 아닌 lib.rs가 생성 되었다는 점이다. main.rs가 존재하지 않는 다는 것은 main()이 존재하지 않는다는 의미이고 더 나아가 프로그램이 실행되는 entry point가 존재하지 않는다는 것을 의미한다. 다시말해, 라이브러리만 가지고는 단독 실행이 불가능하다. 이것을 확인하는 확실한 방법은 cargo run을 실행해 보는 것이다. 아마 실행해 보면 bin이 아니기 때문에 실행할 수 없다는 에러가 출력될 것이다. 그러니 라이브러리를 작성할 땐 cargo build를 애용 하도록 하자.

아래는 자동 생성된 lib.rs 이다.

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }
}

모듈 정의

네트워크 모듈을 만들기 위해 netowrk 모듈과 connect()라는 메소드를 정의해 보자.

#[cfg(test)]
mod network {
    #[test]
    fn connect() {

    }
}

앞에서 배웠던 매소드를 작성했던 방법과 유사하다. impl 이 mod로 바뀌었다고 생각하면 이해하기 편할 것 같다. 나중에 나오겠지만, 네임스페이스를 사용하여 호출하는 것도 비슷한 점 중 하나이다 (netowrk::connect()). 네임스페이스를 사용하기 때문에 다른 모듈에서 같은 메소드 이름을 사용하는건 당연히 허용된다.

mod network { 
    fn connect() { } 
}
mod client { 
    fn connect() { } 
} 

이 두 개의 메소드는 각각 network::connect() , client::connect()로 접근할 수 있다. 심지어 모듈 안에 모듈을 작성하는 것도 가능하다! connect() 메소드는 두 개 모두 network() 관련 메소드이므로 네트워크 모듈 안에 넣어보자.

mod network {
    fn connect() {
    }

    mod client {
        fn connect() {
        }
    }
}

이제 메소드를 사용 하려면 netowrk::connect() , network::client::connect()로 코드를 작성 하면 된다. 이렇게 모듈을 계층화하고, 잘개 나누는 것은 순전히 개발자 마음이다. 클린하고 퓨어하고 우아한 코드를 위해 계층을 잘 나누어 보자.

모듈을 다른 파일로 옮기기

하나의 파일에 모든 모듈을 작성 하는 것 보다는 모듈에 따라 파일도 나누어 작성하는것이 좋다. 아래와 같은 모듈을 작성하고 파일별로 쪼개어 보자.

mod client {
    fn connect() {
    }
}

mod network {
    fn connect() {
    }

    mod server {
        fn connect() {
        }
    }
}

어떻게 쪼갤 수 있을까? 먼저 눈에 띄는 것은 client 와 network 모듈이다. 서로 동등한 계층에 있고, 성격도 다르다. client.rs 파일을 생성하고, 모듈 코드를 옮겨 적어주자. network 모듈은 server 모듈을 포함하고 있어, 한번 더 분리해야 할 것 같으니 일단은 가만히 두자.

src/client.rs


fn connect() {

}

src/lib.rs

mod network {
    fn connect() {
    }

    mod server {
        fn connect() {

        }
    }
}

이제 lib.rs를 분리해 보자. network 모듈은 그대로 connect를 가지고 있어야 하고, server 모듈은 network모듈의 하위모듈로 작성 되어야 한다. 하위 모듈을 포함하는 모듈을 작성하려면 폴더를 생성해 주면 된다. 그리고 메소드를 mod.rs에 작성해 주면 된다. 우리의 코드를 예시로 들어보면 아래의 순서이다.


1. network 폴더 생성
2. mod.rs 파일을 생성해 connect 메소드 작성
3. server.rs 파일을 network 폴더 아래에 생성하고 server 모듈의 코드를 옮긴다.


그럼 다음과 같이 작성된다.

src/netowrk/mod.rs

fn connect() {

}

mod server;

src/netowrk/server.rs

fn connect() {

}

여기까지 진행 한다면, 우리가 원한대로 모듈을 파일별로 잘 나누어 작성하게 된다. 이를 파일트리로 나타내면 아래와 같다.

├── src
│   ├── client.rs
│   ├── lib.rs
│   └── network
│       ├── mod.rs
│       └── server.rs

모듈 파일 시스템의 규칙

위에서 주저리 주저리 설명했지만, 간단히 두 가지만 알고 있으면 된다.

  • foo 모듈이 서브 모듈을 가질 때
    • foo/mod.rs 파일에 foo를 선언
  • foo 모듈이 서브 모듈을 가지지 않을 때
    • foo.rs 파일에 foo 선언

이 두 가지만 기억하고 있으면 앞으로 모듈을 생성하는데 큰 어려움은 없을 것이다.

이제 다음으로 pub 키워드에 대해 알아보자.

저작자표시 (새창열림)

'⚙️ Rust > 👀 Tutorial' 카테고리의 다른 글

[Rust / 튜토리얼] 19. 러스트의 use. super의 사용  (0) 2022.06.22
[Rust / 튜토리얼] 18. 러스트의 public 과 private  (0) 2022.06.15
[Rust / 튜토리얼] 16. 러스트의 let if 의 사용법  (0) 2022.06.08
[Rust / 튜토리얼] 15. 러스트에서 match 를 이용한 분기.  (0) 2022.06.06
[Rust / 튜토리얼] 13. 러스트의 열거형과 Option, None 그리고 Some  (0) 2022.06.03
    '⚙️ Rust/👀 Tutorial' 카테고리의 다른 글
    • [Rust / 튜토리얼] 19. 러스트의 use. super의 사용
    • [Rust / 튜토리얼] 18. 러스트의 public 과 private
    • [Rust / 튜토리얼] 16. 러스트의 let if 의 사용법
    • [Rust / 튜토리얼] 15. 러스트에서 match 를 이용한 분기.
    타나기
    타나기
    #include<all>

    티스토리툴바