패키지와 크레이트
크레이트(crate)
가장 작은 코드 단위이다.
바이너리 크레이트는 실행파일로 컴파일할 수 있는 프로그램이다. main
함수를 포함해야 한다.
라이브러리 크레이트는 여러 프로젝트에서 공용될 의도로 만들어진 기능들이 정의되어 있는 크레이트이다. 일반적으로
‘크레이트’라고 하면 라이브러리 크레이트를 말한다. 즉, ‘크레이트’라는 개념은 다른 언어에서의 ‘라이브러리’라고 볼 수 있다.
크레이트 루트 (crate root)는 러스트 컴파일러가 컴파일을 시작하는 소스 파일이고, 크레이트의 루트 모듈을 구성한다.
패키지(package)
패키지는 여러 크레이트의 번들이다. 크레이트를 빌드하는 법이 설명된 Cargo.toml
파일을 포함한다. 패키지에는 여러 바이너리 크레이트가 포함될 수 있고, 라이브러리 크레이트는 하나만 포함할 수 있다.
Cargo new
를 실행하면 디렉토리 파일에 Cargo.toml
이 생성된다. 여기에 src/main.rs
가 명시되어 있지는 않지만 자동으로 생성된다. 패키지명과 같은 이름의 바이너리 크레이트는 src/main.rs
가 크레이트 루트라는 관례를 따른다.
마찬가지로 src/lib.rs
가 존재하면 패키지명과 같은 이름의 라이브러리 크레이트를 포함한다고 판단한다. 크레이트 루트 파일은 rustc
에 전달된다.
src/bin
에 파일을 배치하면 각 파일이 바이너리 크레이트가 되어 여러 바이너리 크레이트를 패키지에 포함할 수 있다.
모듈 정의
다음과 같이 구성된 크레이트가 있다.
backyard
├── Cargo.lock
├── Cargo.toml
└── src
├── garden
│ └── vegetables.rs
├── garden.rs
└── main.rs
현재 크레이트 루트 파일은 main.rs
이다. 내용은 다음과 같다.
use crate::garden::vegetables::Asparagus;
pub mod garden;
fn main() {
let plant = Asparagus {};
println!("I'm growing {:?}!", plant);
}
pub mod garden;
라인이 컴파일러에게 src/garden.rs
에 있는 코드를 포함할 것을 알려주고, src/garden.rs
는 다음과 같다.
pub mod vegetables;
이는 /src/garden/vegetables.rs
가 포함되어야 함을 알린다.
레스토랑이 고객을 안내하는 접객 부서 (front of house) 와 요리, 행정을 담당하는 지원 부서 (back of house) 로 나누어져 있다 하자.
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
키워드로 지정한다. front_of_house
모듈은 hosting
과 serving
이라는 서브 모듈로 이루어져 있다. 각 모듈은 적절한 기능을 수행하는 함수를 포함하고 있다.
크레이트 루트는 크레이트 모듈 구조에서 최상위에 crate
라는 이름을 갖는 일종의 모듈로 형성된다. 위 모듈 구조를 트리로 나타내면 다음과 같다.
crate
└── front_of_house
├── hosting
│ ├── add_to_waitlist
│ └── seat_at_table
└── serving
├── take_order
├── serve_order
└── take_payment
모듈 참조
src/lib.rs
의 내용은 다음과 같다.
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub fn eat_at_restaurant() {
// 절대 경로
crate::front_of_house::hosting::add_to_waitlist();
// 상대 경로
front_of_house::hosting::add_to_waitlist();
}
모듈은 기본적으로 비공개이다. 따라서 다른 곳에서 참조하고자 한다면 pub
키워드를 사용해 공개로 돌려야 한다.
pub mod hosting
으로 모듈을 공개했지만, 내용까지 공개되는 것은 아니다. add_to_waitlist
함수에도 pub
를
추가해야 한다.
front_of_house
는 공개가 아니지만 eat_at_restaurant
와 동일한 모듈 내에 있으므로 참조할 수 있다.
super
super
는 파일 시스템에서 ..
과 같다. 상위 모듈을 참조할 수 있게 해준다.
구조체, 열거형 공개
구조체를 공개해도 구조체의 필드는 비공개이므로, 필드마다 공개 여부를 설정해야 한다.
비공개 필드가 있다면 인스턴스를 생성할 공개 연관 함수를 제공해야 한다. 그렇지 않으면 비공개 필드를 설정할 방법이 없다.
mod back_of_house {
pub struct Breakfast {
pub toast: String,
seasonal_fruit: String,
}
}
열거형은 공개하면 모든 배리언트 역시 공개된다.
mod back_of_house {
pub enum Appetizer {
Soup,
Salad,
}
}
use 키워드
상대경로라 할지라도 매번 경로를 지정하는 건 번거로운 일이다. use
를 사용해 경로를 명시해둘 수 있다.
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
}
use
가 사용된 특정한 스코프에서만 단축경로가 만들어진다.
다음과 같이 전체 경로를 가져올 수도 있지만,
use crate::front_of_house::hosting::add_to_waitlist;
pub fn eat_at_restaurant() {
add_to_waitlist();
}
부모 모듈을 특정해 이 함수가 로컬에서 작성된 것이 아님을 명시하는 편이 좋다.
열거형이나 구조체 등의 아이템을 가져올 때는 전체 경로를 작성하는 것이 보편적이다.
use std::collections::HashMap;
fn main() {
let mut map = HashMap::new();
map.insert(1, 2);
}
as 키워드
use std::fmt::Result;
use std::io::Result as IoResult;
fn function1() -> Result {
// --생략--
}
fn function2() -> IoResult<()> {
// --생략--
}
동일한 이름의 아이템을 가져올 경우, as
를 사용해 별칭을 지정할 수 있다.
pub use
use
로 경로를 가져오면 그 경로는 비공개이다. 만약 코드를 다른 곳에서 이용해야 한다면, 다른 곳에서는 전체 경로를 모두 명시해야 한다.
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
}
pub use
로 경로를 가져오면, 가져온 경로를 외부에서도 접근할 수 있게 된다. 경로를 가져오는 동시에 외부로 공개하는 동작이라 re-exporting이라 부른다.
같은 모듈에 정의된 여러 아이템을 가져올 경우, 중괄호로 중첩할 수 있다.
use std::cmp::Ordering;
use std::io;
//동일한 코드
use std::{cmp::Ordering, io};
별개의 파일로 모듈 분리
src/lib.rs
에서 front_of_house
모듈을 분리해보자.
우선 모듈을 구현한 내용을 다 빼고
mod front_of_house;
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
}
src/front_of_house.rs
파일로 옮긴다.
pub mod hosting {
pub fn add_to_waitlist() {}
}
hosting
모듈은 front_of_house
모듈의 하위 모듈이다.
따라서 front_of_house.rs
에는 모듈 정의만 남기고
pub mod hosting;
src/front_of_house
디렉토리를 만들어 hosting.rs
에 내용을 작성한다.
pub fn add_to_waitlist() {}
'프로그래밍 > Rust' 카테고리의 다른 글
[Rust] 오류 처리 (0) | 2024.05.18 |
---|---|
[Rust] 컬렉션 (0) | 2024.05.18 |
[Rust] 열거형 (0) | 2024.05.17 |
[Rust] 구조체 (0) | 2024.05.16 |
[Rust] 소유권 (0) | 2024.05.16 |