W Rust modyfikatory widoczności zarządzają dostępem do elementów modułów (struktur, funkcji, stałych itd.). Domyślnie wszystko, co jest zadeklarowane w module, jest prywatne (dostępne tylko w danym module). Istnieją specjalne modyfikatory:
pub: czyni element publicznym (widocznym z jakichkolwiek zewnętrznych modułów).pub(crate): widoczność ograniczona do bieżącego crate (pakietu).pub(super): widoczność ograniczona do nadrzędnego modułu.pub(in path): widoczność ograniczona do określonej ścieżki.Przykład:
mod foo { pub struct Bar { pub x: i32, // pole dostępne wszędzie y: i32, // pole prywatne } pub(crate) fn crate_fn() {} pub(super) fn super_fn() {} fn private_fn() {} }
Główna różnica w porównaniu do np. C++ lub Javy polega na tym, że nie ma oddzielnego poziomu dla protected, a dostępność jest ściśle kontrolowana na poziomie modułów/ścieżek, a nie hierarchii klas.
Pytanie: Jeśli struktura jest zadeklarowana jako pub struct Foo, czy jej prywatne pola będą dostępne w innym module tego samego projektu?
Często odpowiadają: Tak, ponieważ struktura jest publiczna.
Poprawna odpowiedź: Nie, tylko sama struktura (Foo) stanie się widoczna, a jej pola będą dostępne tylko wtedy, gdy również zostaną zadeklarowane z modyfikatorem pub. Pola bez pub pozostają prywatne, nawet jeśli sama struktura jest publiczna.
Przykład:
mod foo { pub struct Bar { pub x: i32, y: i32, } } fn main() { let bar = foo::Bar { x: 1, y: 2 }; // Błąd: pole `y` niedostępne }
Historia
W dużym projekcie publicznie eksportowano strukturę przez pub, ale pola pozostawiono prywatnymi domyślnie. Inne moduły nie mogły tworzyć instancji struktury bezpośrednio, a jedynym rozwiązaniem było napisanie dodatkowych konstruktorów lub zadeklarowanie odpowiednich pól jako pub. To spowodowało problemy z API aż do ostatecznego zakończenia prac.
Historia
Jeden z deweloperów w bibliotece używał tylko pub(crate) dla funkcji, przypuszczając możliwość ich wywołania z binarnych projektów korzystających z tej biblioteki. Jednak takie funkcje stały się niedostępne w zewnętrznym binarnym crate, co spowodowało problemy z integracją.
Historia
W jednej z wtyczek do serwera API użyto pub(super) dla struktur, ale z czasem pojawiła się potrzeba dostępu do nich z innych modułów; z powodu ustawienia widoczności trzeba było w wielu miejscach znacznie przepisz moduły, aby zapewnić odpowiedni zakres widoczności bez naruszania enkapsulacji.