¿"Pub" está destinado a indicar de público a caja o de público a módulo? [duplicar]
Para hacer públicos los métodos de un submódulo, debe reexportarlos explícitamente o, de lo contrario, hacer público el submódulo:
mod foo {
mod bar {
pub fn baz() {}
}
pub use self::bar::baz;
}
Esto parece sugerir que pub
se usa para indicar que algo debería ser público solo para un módulo (ya que puede elegir no hacer esto)
Pero si usa un tipo privado definido en el contexto externo, obtendrá un error si intenta hacer pública una función pública que lo involucre en el contexto interno incluso cuando no se reexporta.
mod foo {
struct Foo;
mod bar {
use super::Foo;
pub fn baz(foo: Foo) {}
}
}
resultados en
error[E0446]: private type `Foo` in public interface
--> src/lib.rs:7:9
|
2 | struct Foo;
| - `Foo` declared as private
...
7 | pub fn baz(foo: Foo) {}
| ^^^^^^^^^^^^^^^^^^^^ can't leak private type
¿Cuál es la forma idiomática de usar la pub
palabra clave? ¿Debería reservarse para cosas que son realmente públicas o se puede utilizar para módulos internos?
Respuestas
La razón por la que su ejemplo no se compila es, en última instancia, porque el RFC (136) lo dice. (Ver también el número 22261 )
¿Qué restricciones se aplican a los artículos públicos?
Las reglas para varios tipos de elementos públicos son las siguientes:
- Si se trata de una
static
declaración, los elementos a los que se hace referencia en su tipo deben ser públicos.- Si se trata de una
fn
declaración, los elementos a los que se hace referencia en sus límites de características, tipos de argumentos y tipo de retorno deben ser públicos.- Si es una declaración
struct
oenum
, los elementos a los que se hace referencia en sus límites de características y en los tipos de suspub
campos deben ser públicos.- Si se trata de una
type
declaración, los elementos a los que se refiere su definición deben ser públicos.- Si se trata de una
trait
declaración, los elementos a los que se hace referencia en sus super-rasgos, en los límites de los rasgos de sus parámetros de tipo y en las firmas de sus métodos (verfn
caso anterior) deben ser públicos.
En resumen, baz
no está permitido pub
porque tiene un argumento que es de tipo privado. Por lo tanto, si baz
es pub
así, permitiría al padre mod foo
reexportar baz
haciendo pub use bar::baz;
. Por supuesto, esto no está permitido, y esta es la razón por la que el ejemplo en su conjunto es ilegal.
Algunos han mencionado anteriormente que pub fn baz
debería permitirse y, en cambio, dar un error de compilación en caso de que el módulo padre lo reexporta. Sin embargo, eso requeriría un análisis estático más complejo para detectar y, en última instancia, no se ha realizado porque el RFC definió que es ilegal.
pub
especifica que el módulo principal puede acceder al elemento. Si todos los antepasados del módulo lo son pub
, entonces la caja exporta ese elemento como un todo.
La palabra clave
pub
hace que cualquier módulo, función o estructura de datos sea accesible desde el interior de módulos externos. Lapub
palabra clave también se puede utilizar en unause
declaración para reexportar un identificador de un espacio de nombres.- Documentación de óxido
Con la noción de que un elemento es público o privado, Rust permite el acceso al elemento en dos casos:
- Si un elemento es público, entonces se puede acceder externamente desde algún módulo m si puede acceder a todos los módulos ancestros del elemento desde m. También puede potencialmente poder nombrar el artículo mediante reexportaciones. Vea abajo.
- Si un elemento es privado, el módulo actual y sus descendientes pueden acceder a él.
- The Rust Reference - Visibilidad y privacidad