programowanieRust backend developer

Wyjaśnij, jak działa system modułów (modules) i widoczność (pub, pub(crate), private) w Rust. Jak można zorganizować duży projekt i uniknąć konfliktów nazw?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

System modułów w Rust opiera się na słowie kluczowym mod. Moduły pozwalają logicznie dzielić kod na pliki i przestrzenie nazw. Kluczowe kwestie:

  • Wszystko domyślnie jest prywatne (private) w ramach bieżącego modułu.
  • pub sprawia, że element jest publiczny dla całego drzewa modułów.
  • pub(crate) — dostępny w całym crate (tj. bibliotece/projekcie).
  • Konflikty nazw są rozwiązywane przez przestrzenie nazw: wyraźne importowanie (use mod_name::item) i aliasy.

W przypadku dużych projektów zaleca się używanie drzewa modułów z opisem publicznych interfejsów tylko przez lib.rs lub main.rs, reszta jest prywatna:

mod network; mod storage; pub use network::api;

Pytanie z haczykiem

Jeśli struktura jest zadeklarowana jako pub, czy będzie dostępna dla innych crate?

Odpowiedź: Nie, nie wystarczy po prostu oznaczyć struct jako pub. Musi być również zadeklarowana w module otwartym dla zewnętrznych crate (pub mod), a pola struktury muszą być publiczne, aby uzyskać do nich bezpośredni dostęp.

Przykład:

mod foo { pub struct Bar; } // Bar nie jest widoczny poza crate, ponieważ foo jest prywatny

Przykłady rzeczywistych błędów spowodowanych brakiem wiedzy na temat tego tematu


Historia

W projekcie o skomplikowanej strukturze modułów przypadkowo zadeklarowano strukturę jako pub, ale nie wyeksportowano modułu jako pub. Później próbowano użyć struktury z innego crate — otrzymano błąd o niedostępności typu.

Historia

W dużej bibliotece różne moduły eksportowały identyczne nazwy (na przykład, types i errors). Przy ślepym użyciu use * wystąpiły konflikty nazw na etapie kompilacji. Rozwiązaniem było dodanie pseudonimów i importowanie tylko potrzebnych elementów.

Historia

Wielu nowicjuszy tworzy strukturę pub, ale pozostawia pola prywatne, co uniemożliwia ich inicjalizację poza modułem. W rezultacie funkcja z innego modułu nie mogła bezpośrednio utworzyć struktury, co powodowało błędy, dopóki nie uczynili pól lub konstruktorów publicznymi.