Modulos
## Objetivos de Aprendizaje
- Organizar codigo con modulos
- Controlar visibilidad con pub
- Usar sentencias use
- Trabajar con crates y paquetes
- Comprender el sistema de modulos
## Por que Modulos?
Los modulos organizan el codigo en unidades logicas:
- Agrupar funcionalidad relacionada
- Controlar visibilidad (publico/privado)
- Evitar conflictos de nombres
- Habilitar reutilizacion de codigo
## Vista General del Sistema de Modulos
```text
crate
└── module
├── submodule
└── subsubmodule
```
## Definiendo Modulos
### Modulos en Linea
```rust
mod network {
fn connect() {
println!("Connecting...");
}
pub fn send(data: &str) {
connect();
println!("Sending: {}", data);
}
}
fn main() {
network::send("hello");
}
```
### Sistema de Archivos de Modulos
```text
src/
├── main.rs
├── network.rs (o network/mod.rs)
└── network/
└── mod.rs
```
### network.rs
```rust
pub fn send(data: &str) {
connect();
println!("Sending: {}", data);
}
fn connect() {
println!("Connecting...");
}
```
### main.rs
```rust
mod network;
fn main() {
network::send("hello");
}
```
## Visibilidad
### Publico (pub)
```rust
mod outer {
pub mod inner {
pub fn public_function() {
println!("Public!");
}
pub(crate) fn crate_public() {
println!("Crate public!");
}
fn private_function() {
println!("Private!");
}
}
}
fn main() {
outer::inner::public_function();
// outer::inner::private_function(); // Error!
}
```
### Privado
```rust
mod outer {
fn private() {
println!("Private outer");
}
pub fn public() {
private(); // Puede llamar a private
}
mod inner {
fn private_inner() {}
pub fn public_inner() {
private_inner(); // Puede llamar a private del hermano
}
}
pub mod public_inner {
pub fn from_public_inner() {}
}
}
```
### pub(super) y pub(in path)
```rust
mod outer {
pub mod middle {
pub mod inner {
pub fn function() {}
}
pub(in outer) fn outer_only() {}
}
pub fn use_inner() {
middle::inner::function();
middle::outer_only(); // OK: dentro de outer
}
}
```
## Sentencias use
### Traer Items al Alcance
```rust
mod network {
pub fn send(data: &str) {
println!("Sending: {}", data);
}
}
use network::send; // Traer al alcance
fn main() {
send("hello"); // Llamada directa
}
```
### Ruta Completa
```rust
use std::collections::HashMap;
fn main() {
let mut map = HashMap::new();
map.insert("a", 1);
}
```
### Rutas Anidadas
```rust
use std::collections::{HashMap, HashSet};
use std::io::{self, Write}; // Incluye io mismo
// O glob
use std::collections::*;
```
### Renombrar con as
```rust
use std::io::Result as IoResult;
use std::fmt::Result as FmtResult;
fn my_function() -> IoResult<()> {
Ok(())
}
```
### Re-exportando con pub use
```rust
mod inner {
pub mod deeply {
pub fn nested_function() {}
}
}
pub use inner::deeply;
fn main() {
deeply::nested_function(); // Re-exportado al alcance externo
}
```
## Visibilidad de Structs
```rust
mod my_module {
pub struct Secret {
pub data: String, // Campo publico
internal: String, // Campo privado (dentro del crate)
secret: String, // Campo privado (solo en el modulo)
}
impl Secret {
pub fn new(data: String) -> Self {
Secret {
data,
internal: data.clone(),
secret: data,
}
}
pub fn get_internal(&self) -> &str {
&self.internal
}
}
}
fn main() {
let s = my_module::Secret::new("secret".to_string());
println!("{}", s.data); // OK: publico
// println!("{}", s.internal); // Error: privado
println!("{}", s.get_internal()); // OK: metodo accesor
}
```
## Visibilidad de Enums
```rust
mod network {
pub enum PacketType {
Data, // Publico por defecto
Ack,
}
pub struct Packet {
pub packet_type: PacketType, // Campo publico
data: Vec, // Campo privado
}
impl Packet {
pub fn new(packet_type: PacketType) -> Self {
Packet {
packet_type,
data: Vec::new(),
}
}
}
}
fn main() {
let packet = network::Packet::new(network::PacketType::Data);
println!("{:?}", packet.packet_type);
}
```
## Crates
### Crate de Libreria
```text
my_crate/
├── Cargo.toml
└── src/
└── lib.rs
```
### src/lib.rs
```rust
pub mod utilities {
pub fn helper() {}
}
```
### Usando Crate de Libreria
```rust
use my_crate::utilities;
fn main() {
utilities::helper();
}
```
### Crate Binario
```text
my_project/
├── Cargo.toml
└── src/
└── main.rs
```
## Paquetes
Un paquete contiene uno o mas crates:
- Un crate de libreria (lib.rs) O
- Uno o mas crates binarios (bin/)
```text
my_package/
├── Cargo.toml
├── src/
│ └── main.rs
└── src/
└── lib.rs (opcional)
```
## El Arbol de Modulos
```rust
// src/main.rs o src/lib.rs
mod network { // network.rs o network/mod.rs
pub mod client;
pub mod server;
}
mod database { // database.rs o database/mod.rs
pub mod connection;
}
fn main() {
network::client::connect();
database::connection::connect();
}
```
## Mejores Practicas
### Estructura de Archivos
```text
src/
├── main.rs (raiz del crate binario)
├── lib.rs (raiz del crate de libreria)
├── network/
│ ├── mod.rs
│ └── client.rs
│ └── server.rs
└── database/
├── mod.rs
└── connection.rs
```
### Nomenclatura de Modulos
```rust
mod my_module; // snake_case
mod myGreatModule; // No hacer esto
```
### Convenciones de Uso
```rust
// Traer modulo padre al alcance
mod outer {
pub mod inner {
pub fn function() {}
}
}
mod outer2 {
pub use super::outer::inner; // Re-exportar desde el padre
pub mod nested {
pub fn call_function() {
super::function(); // Llamar funcion del padre
}
}
}
```
## Resumen
- Los modulos organizan el codigo logicamente
- La palabra clave `mod` declara modulos
- Los archivos pueden ser modulos: `mod name;` busca `name.rs` o `name/mod.rs`
- `pub` hace los items publicos
- Los items privados solo son visibles dentro del modulo que los declara
- `use` trae items al alcance
- `pub use` re-exporta items
- `super` se refiere al modulo padre
- Los paquetes contienen crates (una lib + bins opcionales)
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →