소개
Packages and Crates에 오신 것을 환영합니다. 이 랩은 Rust Book의 일부입니다. LabEx 에서 Rust 기술을 연습할 수 있습니다.
이 랩에서는 패키지와 크레이트를 다룰 것입니다. 여기서 크레이트는 Rust 컴파일러가 고려하는 가장 작은 코드 단위이며, 바이너리 크레이트 또는 라이브러리 크레이트가 될 수 있습니다. 패키지는 일련의 기능을 제공하는 하나 이상의 크레이트 모음입니다.
Packages and Crates에 오신 것을 환영합니다. 이 랩은 Rust Book의 일부입니다. LabEx 에서 Rust 기술을 연습할 수 있습니다.
이 랩에서는 패키지와 크레이트를 다룰 것입니다. 여기서 크레이트는 Rust 컴파일러가 고려하는 가장 작은 코드 단위이며, 바이너리 크레이트 또는 라이브러리 크레이트가 될 수 있습니다. 패키지는 일련의 기능을 제공하는 하나 이상의 크레이트 모음입니다.
모듈 시스템의 첫 번째 부분은 패키지와 크레이트입니다.
*크레이트 (crate)*는 Rust 컴파일러가 한 번에 고려하는 가장 작은 코드 단위입니다. cargo 대신 rustc를 실행하고 단일 소스 코드 파일을 전달하더라도 ( "Rust 프로그램 작성 및 실행"에서 했던 것처럼), 컴파일러는 해당 파일을 크레이트로 간주합니다. 크레이트는 모듈을 포함할 수 있으며, 모듈은 다음 섹션에서 보듯이 크레이트와 함께 컴파일되는 다른 파일에서 정의될 수 있습니다.
크레이트는 바이너리 크레이트 또는 라이브러리 크레이트의 두 가지 형태로 제공될 수 있습니다. *바이너리 크레이트 (binary crate)*는 명령줄 프로그램이나 서버와 같이 실행 가능한 파일로 컴파일하여 실행할 수 있는 프로그램입니다. 각 바이너리 크레이트는 실행 파일이 실행될 때 발생하는 일을 정의하는 main 함수를 가져야 합니다. 지금까지 생성한 모든 크레이트는 바이너리 크레이트였습니다.
*라이브러리 크레이트 (library crate)*는 main 함수가 없으며 실행 파일로 컴파일되지 않습니다. 대신, 여러 프로젝트에서 공유할 기능을 정의합니다. 예를 들어, 2 장에서 사용한 rand 크레이트는 난수를 생성하는 기능을 제공합니다. Rust 개발자들이 "크레이트"라고 말할 때는 대부분 라이브러리 크레이트를 의미하며, "크레이트"를 "라이브러리"라는 일반적인 프로그래밍 개념과 상호 교환적으로 사용합니다.
*크레이트 루트 (crate root)*는 Rust 컴파일러가 시작하는 소스 파일이며 크레이트의 루트 모듈을 구성합니다 ( "범위 및 개인 정보를 제어하기 위한 모듈 정의"에서 모듈에 대해 자세히 설명합니다).
*패키지 (package)*는 일련의 기능을 제공하는 하나 이상의 크레이트 묶음입니다. 패키지에는 해당 크레이트를 빌드하는 방법을 설명하는 Cargo.toml 파일이 포함되어 있습니다. Cargo 는 실제로 코드를 빌드하는 데 사용해 온 명령줄 도구에 대한 바이너리 크레이트를 포함하는 패키지입니다. Cargo 패키지에는 바이너리 크레이트가 의존하는 라이브러리 크레이트도 포함되어 있습니다. 다른 프로젝트는 Cargo 명령줄 도구가 사용하는 것과 동일한 로직을 사용하기 위해 Cargo 라이브러리 크레이트에 의존할 수 있습니다.
크레이트는 바이너리 크레이트 또는 라이브러리 크레이트의 두 가지 형태로 제공될 수 있습니다. 패키지는 원하는 만큼 많은 바이너리 크레이트를 포함할 수 있지만, 최대 하나의 라이브러리 크레이트만 포함할 수 있습니다. 패키지에는 라이브러리 또는 바이너리 크레이트 중 하나 이상이 포함되어야 합니다.
패키지를 생성할 때 발생하는 상황을 살펴보겠습니다. 먼저 cargo new my-project 명령을 입력합니다.
$ cargo new my-project
Created binary (application) `my-project` package
$ ls my-project
Cargo.toml
src
$ ls my-project/src
main.rs
cargo new my-project를 실행한 후 ls를 사용하여 Cargo 가 생성하는 것을 확인합니다. 프로젝트 디렉토리에는 Cargo.toml 파일이 있으며, 이는 패키지를 제공합니다. 또한 src 디렉토리에는 main.rs가 포함되어 있습니다. 텍스트 편집기에서 Cargo.toml을 열고 src/main.rs에 대한 언급이 없다는 점에 유의하십시오. Cargo 는 src/main.rs가 패키지와 동일한 이름의 바이너리 크레이트의 크레이트 루트라는 규칙을 따릅니다. 마찬가지로, Cargo 는 패키지 디렉토리에 src/lib.rs가 포함되어 있으면 패키지에 패키지와 동일한 이름의 라이브러리 크레이트가 포함되어 있고 src/lib.rs가 해당 크레이트 루트임을 알고 있습니다. Cargo 는 라이브러리 또는 바이너리를 빌드하기 위해 크레이트 루트 파일을 rustc에 전달합니다.
여기에는 src/main.rs만 포함된 패키지가 있습니다. 즉, my-project라는 바이너리 크레이트만 포함합니다. 패키지에 src/main.rs와 src/lib.rs가 포함되어 있으면 두 개의 크레이트가 있습니다. 바이너리와 라이브러리, 둘 다 패키지와 동일한 이름을 갖습니다. 패키지는 src/bin 디렉토리에 파일을 배치하여 여러 바이너리 크레이트를 가질 수 있습니다. 각 파일은 별도의 바이너리 크레이트가 됩니다.
모듈 치트 시트
모듈과 경로에 대한 세부 사항을 살펴보기 전에, 모듈, 경로,
use키워드 및pub키워드가 컴파일러에서 어떻게 작동하는지, 그리고 대부분의 개발자가 코드를 구성하는 방법에 대한 간략한 참조를 제공합니다. 이 장에서 이러한 규칙의 각 예제를 살펴볼 것이지만, 모듈이 작동하는 방식을 상기시키는 데 유용한 곳입니다.
- 크레이트 루트에서 시작: 크레이트를 컴파일할 때 컴파일러는 먼저 크레이트 루트 파일 (일반적으로 라이브러리 크레이트의 경우
src/lib.rs또는 바이너리 크레이트의 경우src/main.rs) 에서 컴파일할 코드를 찾습니다.- 모듈 선언: 크레이트 루트 파일에서 새 모듈을 선언할 수 있습니다. 예를 들어,
mod garden;으로 "garden" 모듈을 선언합니다. 컴파일러는 모듈의 코드를 다음 위치에서 찾습니다.
- 인라인으로,
mod garden다음에 세미콜론 대신 중괄호 안에- 파일
src/garden.rs에서- 파일
src/garden/mod.rs에서- 하위 모듈 선언: 크레이트 루트가 아닌 모든 파일에서 하위 모듈을 선언할 수 있습니다. 예를 들어,
src/garden.rs에서mod vegetables;를 선언할 수 있습니다. 컴파일러는 하위 모듈의 코드를 상위 모듈의 이름을 딴 디렉토리 내에서 다음 위치에서 찾습니다.
- 인라인으로,
mod vegetables바로 뒤에 세미콜론 대신 중괄호 안에- 파일
src/garden/vegetables.rs에서- 파일
src/garden/vegetables/mod.rs에서- 모듈의 코드에 대한 경로: 모듈이 크레이트의 일부가 되면, 개인 정보 보호 규칙이 허용하는 한, 코드에 대한 경로를 사용하여 동일한 크레이트의 다른 곳에서 해당 모듈의 코드를 참조할 수 있습니다. 예를 들어, garden vegetables 모듈의
Asparagus타입은crate::garden::vegetables::Asparagus에서 찾을 수 있습니다.- Private vs. public: 모듈 내의 코드는 기본적으로 상위 모듈에서 private 입니다. 모듈을 public 으로 만들려면
mod대신pub mod로 선언합니다. public 모듈 내의 항목도 public 으로 만들려면 선언 앞에pub를 사용합니다.- use 키워드: 범위 내에서
use키워드는 긴 경로의 반복을 줄이기 위해 항목에 대한 바로 가기를 만듭니다.crate::garden::vegetables::Asparagus를 참조할 수 있는 모든 범위에서use crate::garden::vegetables::Asparagus;를 사용하여 바로 가기를 만들 수 있으며, 그 후에는 해당 범위에서 해당 타입을 사용하기 위해Asparagus만 작성하면 됩니다.여기서는 이러한 규칙을 보여주는
backyard라는 바이너리 크레이트를 만듭니다.backyard라는 크레이트의 디렉토리에는 다음과 같은 파일과 디렉토리가 포함되어 있습니다.backyard ├── Cargo.lock ├── Cargo.toml └── src ├── garden │ └── vegetables.rs ├── garden.rs └── main.rs이 경우 크레이트 루트 파일은
src/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에서 찾은 코드를 포함하도록 지시합니다. 이 코드는 다음과 같습니다.pub mod vegetables;여기서
pub mod vegetables;는src/garden/vegetables.rs의 코드도 포함됨을 의미합니다. 해당 코드는 다음과 같습니다.#[derive(Debug)] pub struct Asparagus {}이제 이러한 규칙의 세부 사항을 살펴보고 실제로 시연해 보겠습니다!
축하합니다! Packages and Crates 랩을 완료했습니다. LabEx 에서 더 많은 랩을 연습하여 기술을 향상시킬 수 있습니다.