ProgramaciónDesarrollador Backend

¿Cómo se implementa en Rust el trabajo con modificadores de visibilidad (pub, pub(crate), pub(super)) y en qué se diferencian de los modificadores en otros lenguajes? ¿Qué problemas pueden surgir con una configuración incorrecta de la visibilidad de los elementos del módulo?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

En Rust, los modificadores de visibilidad controlan el acceso a los elementos de los módulos (estructuras, funciones, constantes, etc.). Por defecto, todo lo que se declara en un módulo es privado (accesible solo en ese módulo). Existen modificadores especiales:

  • pub: hace que el elemento sea público (visible desde cualquier módulo externo).
  • pub(crate): la visibilidad está limitada al crate actual (paquete).
  • pub(super): la visibilidad está limitada al módulo padre.
  • pub(in path): la visibilidad está limitada a un camino específico.

Ejemplo:

mod foo { pub struct Bar { pub x: i32, // campo accesible en todas partes y: i32, // campo privado } pub(crate) fn crate_fn() {} pub(super) fn super_fn() {} fn private_fn() {} }

La principal diferencia con, por ejemplo, C++ o Java, es que no hay un nivel separado para protected, y la accesibilidad se controla estrictamente a nivel de módulos/rutas, no de jerarquía de clases.

Pregunta capciosa.

Pregunta: Si una estructura se declara como pub struct Foo, ¿sus campos privados serán accesibles en otro módulo del mismo proyecto?

Respuesta común: Sí, ya que la estructura es pública.

Respuesta correcta: No, solo la propia estructura (Foo) será visible, y sus campos solo si también se declaran con el modificador pub. Los campos sin pub permanecen privados, incluso si la propia estructura es pública.

Ejemplo:

mod foo { pub struct Bar { pub x: i32, y: i32, } } fn main() { let bar = foo::Bar { x: 1, y: 2 }; // Error: campo `y` no accesible }

Ejemplos de errores reales debido a la falta de conocimiento de los matices del tema.


Historia

En un gran proyecto, se exportó públicamente una estructura a través de pub, pero los campos se dejaron privados por defecto. Otros módulos no podían crear instancias de la estructura directamente, y la única solución fue escribir constructores adicionales o declarar los campos necesarios como pub. Esto causó un fallo en el API hasta su finalización.


Historia

Uno de los desarrolladores en la biblioteca utilizó solo pub(crate) para funciones, suponiendo la posibilidad de ser llamadas desde proyectos binarios que usan esta biblioteca. Sin embargo, tales funciones se volvieron inaccesibles en un crate binario externo, lo que causó problemas durante la integración.


Historia

En uno de los plugins del servidor API se utilizaron pub(super) para estructuras, pero con el tiempo surgió la necesidad de acceder a ellas desde otros módulos; debido a la configuración de visibilidad, hubo que reescribir radicalmente módulos en varios lugares para proporcionar el ámbito de visibilidad necesario sin romper la encapsulación.