Paquetes y Crates
Las primeras partes del sistema de módulos que cubriremos son los paquetes y los crates.
Un crate es la cantidad más pequeña de código que el compilador Rust considera
a la vez. Incluso si ejecutas rustc
en lugar de cargo
y pasas un solo
archivo de código fuente (como lo hicimos en la sección “Escribir y Ejecutar un
Programa Rust” del Capítulo 1), el compilador considera que ese archivo es un
crate. Los crates pueden contener módulos, y los módulos pueden definirse en
otros archivos que se compilan con el crate, como veremos en las próximas
secciones.
Un crate puede venir en una de dos formas: un crate binario o un crate de
biblioteca. Los crates binarios son programas que puedes compilar a un
ejecutable que puedes ejecutar, como un programa de línea de comandos o un
servidor. Cada uno debe tener una función llamada main
que defina lo que
sucede cuando se ejecuta el ejecutable. Todos los crates que hemos creado hasta
ahora han sido crates binarios.
Los crates de biblioteca no tienen una función main
, y no se compilan a un
ejecutable. En su lugar, definen funcionalidad destinada a ser compartida con
múltiples proyectos. Por ejemplo, el crate rand
que usamos en el Capítulo
2 proporciona funcionalidad que genera números aleatorios.
La mayor parte del tiempo, cuando los Rustaceans dicen “crate”, se refieren a
crate de biblioteca, y usan “crate” indistintamente con el concepto general de
programación de una “biblioteca”.
El crate root es un archivo fuente que el compilador Rust comienza y forma el módulo raíz de tu crate (explicaremos los módulos en profundidad en la sección “Definir Módulos para Controlar el Alcance y la Privacidad”).
Un paquete es un conjunto de uno o más crates que proporciona un conjunto de funcionalidades. Un paquete contiene un archivo Cargo.toml que describe cómo compilar esos crates. Cargo es en realidad un paquete que contiene el crate binario para la herramienta de línea de comandos que has estado usando para compilar tu código. El paquete Cargo también contiene un crate de biblioteca en el que el crate binario depende. Otros proyectos pueden depender del crate de biblioteca Cargo para usar la misma lógica que la herramienta de línea de comandos Cargo usa.
Un paquete puede venir en dos formas: un paquete binario o un paquete libreria. Un paquete puede contener tantos crates binarios como desees, pero como máximo solo un crate de biblioteca. Un paquete debe contener al menos un crate, ya sea un crate de biblioteca o un crate binario.
Veamos qué sucede cuando creamos un paquete. Primero, ingresamos el comando
cargo new
:
$ cargo new my-project
Created binary (application) `my-project` package
$ ls my-project
Cargo.toml
src
$ ls my-project/src
main.rs
Después de ejecutar cargo new my-project
, usamos ls
para ver lo que crea
Cargo. En el directorio del proyecto, hay un archivo Cargo.toml, que nos da un
paquete. También hay un directorio src que contiene main.rs. Abre
Cargo.toml en tu editor de texto, y observa que no hay mención de
src/main.rs. Cargo sigue una convención de que src/main.rs es la raíz del
crate de un crate binario con el mismo nombre que el paquete. Del mismo modo,
Cargo sabe que si el directorio del paquete contiene src/lib.rs, el paquete
contiene un crate de biblioteca con el mismo nombre que el paquete, y
src/lib.rs es su raíz del crate. Cargo pasa los archivos raíz del crate a
rustc
para compilar la biblioteca o el binario.
Aquí, tenemos un paquete que solo contiene src/main.rs, lo que significa que
solo contiene un crate binario llamado my-project
. Si un paquete contiene
src/main.rs y src/lib.rs, tiene dos crates: un binario y una biblioteca,
ambos con el mismo nombre que el paquete. Un paquete puede tener múltiples
crates binarios colocando archivos en el directorio src/bin: cada archivo será
un crate binario separado.