18 · Módulos
Módulos inline y visibilidad granular
Módulos declarados dentro del archivo, `use ... as`, y modificadores `pub(mod)` / `pub(crate)`.
En esta página
Además de módulos en archivos separados, Zolo permite declarar un módulo
inline dentro del propio archivo con mod nombre { ... }. Es útil para
agrupar funciones relacionadas sin crear un archivo extra.
use ... as nombre (renombrado) crea un alias local — conveniente cuando el
nombre original es largo o colisiona con otro nombre en el ámbito. Los
modificadores de visibilidad pub(mod) y pub(crate) permiten un control más
fino que el simple pub:
pub(mod)— visible para los miembros del mismo módulo inline, pero invisible fuera de él.pub(crate)— visible en todo el crate (equivale apubhoy, pero el parser preserva la información para fases futuras del compilador).
mod arith { ... } se declara inline; use std::math::{abs as absolute, sign} renombra durante la importación; pub(mod) secret_factor es usable por
triple (mismo módulo) pero no por el código externo.
// Feature: inline `mod foo { ... }`, `use ... as ...` rename, granular
// visibility (private, `pub`, `pub(crate)`, `pub(super)`, `pub(in ...)`,
// `pub(mod)`) and origin-preserving re-exports.
// See `specs/mod-namespace-innovations.html` (cherry-picks C1, C4).
use std::math::{abs as absolute, sign}
// Inline module — declared inside this file, not loaded from disk.
mod arith {
// No modifier: private to canonical module `crate::arith`.
fn private_bias() -> int { 1 }
pub fn add(a: int, b: int) -> int { a + b + private_bias() - 1 }
pub fn mul(a: int, b: int) -> int { a * b }
// pub(mod) keeps the item visible to siblings inside `arith` but
// hidden to the outside file.
pub(mod) fn secret_factor() -> int { 3 }
// pub(crate) crosses module boundaries only inside this crate. The
// resolver, VM/AOT lowerers and editor all use the same canonical region.
pub(crate) fn triple(x: int) -> int { x * secret_factor() }
// The canonical identities are `crate::arith::scoped` and
// `crate::arith::origin`; the local names below are only aliases.
mod scoped {
pub(super) fn parent_only() -> int { 4 }
pub(in crate::arith) fn arith_only() -> int { 5 }
}
pub fn scoped_total() -> int {
scoped.parent_only() + scoped.arith_only()
}
mod origin {
pub(crate) fn crate_value() -> int { 6 }
pub fn public_value() -> int { 7 }
}
// Plain `pub use` cannot widen `crate_value`: the alias remains crate-only
// because the re-export retains and intersects the declaration's origin.
pub use origin::{crate_value as via_facade, public_value}
}
// Bring two items in with renames; the alias becomes the local name.
fn main() {
print("arith.add(2,3) = {arith.add(2, 3)}") // 5
print("arith.mul(2,3) = {arith.mul(2, 3)}") // 6
print("arith.triple(4) = {arith.triple(4)}") // 12 (uses secret_factor)
print("arith.scoped_total() = {arith.scoped_total()}") // 9
print("arith.via_facade() = {arith.via_facade()}") // 6 (crate-only)
print("arith.public_value() = {arith.public_value()}") // 7 (public)
print("absolute(-7) = {absolute(-7)}") // 7
print("sign(-9) = {sign(-9)}") // -1
}
Desafío
Intenta llamar a arith.secret_factor() desde main. ¿Qué responde el
compilador? Ahora cambia pub(mod) por pub y observa la diferencia.
Consulta también