name keywords etiquetas etiqueta ejemplos description module rust public rust-crates

module - keywords - ¿Cómo hago público un artículo de Rust dentro de una caja, pero privado fuera de él?



meta tags ejemplos (1)

Para que un item pueda exportar desde el cajón de una biblioteca, debe haber al menos un camino que lo lleve a donde cada componente sea público. Esto significa que todo lo que necesita para hacer público un artículo dentro de su caja pero no exportado desde la caja (lo llamaré "interno" de ahora en adelante, para imitar la terminología de C #) es colocarlo en un módulo privado debajo de la raíz de caja. .

Sin embargo, esa solución es bastante restrictiva. ¿Qué sucede si desea tener un módulo con funciones exportadas y funciones internas? Para exportar algunas funciones, necesitamos hacer público el módulo, y eso significa que todos los elementos públicos en ese módulo también serán exportados.

Desde Rust 1.18 , hay una solución adaptada a este tipo de escenario: pub(restricted) . Esta función le permite especificar "cómo público" debe ser un elemento. La sintaxis es bastante flexible (puede hacer que un elemento sea visible para un árbol de módulos particular en lugar de toda la caja), pero si desea mantenerlo simple, pub(crate) hará que un elemento sea accesible en cualquier lugar dentro de la caja, pero no para Otras cajas (equivalentes a las internal en C #).

Por ejemplo, supongamos que nos gustaría tener un módulo util en el que foo se exporta (como mycrate::util::foo ), bar es interno y baz es privado para el módulo. El código podría verse así:

pub mod util { pub fn foo() { unimplemented!() } pub(crate) fn bar() { unimplemented!() } fn baz() { unimplemented!() } }

Si estás atascado en Rust pre-1.18, hay una solución, pero es un poco torpe. Implica definir todos sus artículos en módulos privados y reexportar solo aquellos que desea hacer públicos (con pub use ) en módulos públicos que solo contienen reexportaciones. Aquí es cómo se vería el ejemplo anterior:

pub mod util { pub use util_impl::foo; } mod util_impl { pub fn foo() { unimplemented!() } pub fn bar() { unimplemented!() } fn baz() { unimplemented!() } }

No solo no es fácil de leer y entender, sino que no cubre todas las situaciones en las pub se puede usar pub . Por ejemplo, ¿cómo haría accesibles algunos campos de una estructura exportada en otros módulos en la misma caja sin exportarlos también? La única opción sería exponer un contenedor con un único campo privado cuyo tipo es la estructura que tiene campos públicos; eso funciona bien si quiere ocultar todos los campos de otras cajas, pero no si desea exponer algunos campos y hacer otros campos internos en la misma estructura.

Tengo una caja que tiene mucho código, así que la dividí en varios archivos / módulos. Sin embargo, algunos módulos tienen elementos internos no seguros (por ejemplo, punteros en bruto) que necesito hacer públicos a los diferentes módulos, pero no quiero exponerlos a los usuarios de mi caja. ¿Cómo puedo hacer eso?

La única forma en que puedo pensar es en realidad hacer que mi caja sea solo un módulo grande, pero no hay manera de dividirla en diferentes archivos, aparte de esta solución que parece un poco intrépida.

Normalmente, cuando me enfrento a un problema del mundo real, los ejemplos simples en los documentos de Rust no explican adecuadamente, solo copio una caja popular del mundo real, por ejemplo, git2-rs , pero eso parece hacer que todo sea público, incluso el crudo punteros