[1. 개요]
러스트는 조직화된 방식으로 코드의 재사용을 할 수 있게 해주는 모듈 시스템을 갖추고 있다.
keyword
- mod
=> 새로운 모듈을 선언한다.
=> 모듈 내의 코드는 이 선언 바로 뒤에 중괄호로 묶여서 따라오거나, 다른 파일에 놓을 수 있다. - pub
=> 기본적으로 rust 는 함수, 타입, 상수, 모듈은 private 이다.
=> 이 키워드는 어떤 아이템을 외부에 노출 시킬 수 있게 한다. - use
=> 모듈이나 모듈 내 정의 들을 스코프 안으로 가져온다.
[2. mod 와 파일시스템]
Library crate => 외부 프로젝트에서 의존성으로 추가 할 수 있는 프로젝트
cargo new communicator --lib
아래와 같은 파일시스템이 생성된다.
- communicator\
- src
- lib.rs
- Cargo.toml
- src
lib.rs 는 라이브러리의 시작지점으로 제공되는 파일이다.
- main.rs 는 프로그램의 시작지점으로 제공되는 파일이다(?).
- main 을 포함하는 파일이름이 main.rs 가 아니면 컴파일이 안된다.
- main.rs 에도 모듈을 만들 수 있다.
library crate 인 경우 cargo build 로 만 컴파일이 가능하다.
모듈안에 다른 모듈을 포함하는 것도 가능하다.
lib.rs 가 아래와 같은 경우
// src/lib.rs
mod network {
fn connect() {
}
mod client {
fn connect() {
}
}
}
외부에 제공할 라이브러리는 아래와 같은 중첩된 구조를 갖는다.
communicator (모듈)
=> network (서브모듈)
=> client (서브모듈)
lib.rs 모듈이 정의된 경우는 찾을 수 있다.
그러나 lib.rs 에 모듈이 선언 만 되어있는 경우,
rust 는 같은 경로에서 <"모듈이름".rs> 파일을 찾는다
lib.rs 가 아닌 파일에서 모듈이 선언 된 경우, (서브모듈을 갖는 경우)
컴파일 에러가 발생한다.
이 경우, 해당 모듈 이름으로 디렉터리 선언 후, 구현부를 생성한 디렉터리 밑에 mod.rs 파일에 옮기고,
생성한 디렉터리 밑에. <"모듈이름".rs> 파일을 생성하고 구현한다.
[2.1 개인정리]
cargo new 로 생성 시 명시한 이름이 최상위 모듈로 간주된다.
lib.rs 는 최상위 모듈을이 참조하는 파일이다.
lib.rs 에서 mod 구현 시 <mod 이름 { }> 에 구현하도록 한다.
lib.rs 에서 mod 선언 시 <서브모듈이름.rs> 를 lib.rs 와 같은 경로에 생성하도록 한다.
<서브모듈이름.rs> 내 mod 선언은 불가능하다.
=> 이 경우 모듈이름 으로 디렉터리 생성 후, mod.rs 를 만들고 기존 코드를 복사한다.
=> 새로 생성 된 디렉터리에 <서브모듈이름.rs> 를 생성하고, 구현한다.
[3. 모듈 파일 시스템의 규칙]
- foo 라는 이름의 (최상위)모듈이 서브 모듈을 갖지 않는다면, foo.rs 라는 파일 내 foo 에 대한 선언을 집어넣는다.
- foo 가 서브모듈을 갖는다면, foo/mod.rs 라는 이름의 파일에 foo 에 대한 선언을 집어넣어야 한다.
[4. use]
use 키워드는 스코프 내에서 호출하고 싶어하는 함수의 모듈을 가져와,
긴 함수 호출을 간략화 시킬 수 있게 한다.
(python 에서 from ~ import 와 비슷함)
기존
=> a::seriese::of::nested_modules()
use 사용
=> use a::series::of
=> of::nested_modules();
위 예제에서 of 모듈을 참조하고 싶은 곳 마다, a::series::of 를 전부 사용하기보다는
of 만 사용 할 수 있게 해준다.
열거형의 variant 또한 use 를 이용하여 가져올 수 있다.
중괄호와 쉼표를 구문의 마지막에 위치하여 가져올 아이템을 나열 할 수 있다.
* 를 이용해서 모두 가져올 수 있다.
이 경우, 이름 충돌이 발생할 수 있으므로 주의해야 한다.
모듈에 대한 경로는 항상 현재 모듈을 기준으로 상대적이다.
:: 혹은 super 를 이용해서 상위 모듈에 접근 할 수 있다.