Czy „pub” ma wskazywać publiczne na skrzynkę lub publiczne na moduł? [duplikować]
Aby upublicznić metody z modułu podrzędnego, musisz jawnie wyeksportować je ponownie lub upublicznić sam moduł podrzędny:
mod foo {
mod bar {
pub fn baz() {}
}
pub use self::bar::baz;
}
Wydaje się, że pub
jest to wskazówka, która jest używana do wskazania, że rzecz powinna być publiczna tylko dla modułu (ponieważ możesz tego nie robić)
Ale jeśli używasz typu prywatnego zdefiniowanego w kontekście zewnętrznym, pojawi się błąd, jeśli spróbujesz ustawić publiczną funkcję obejmującą ją w kontekście wewnętrznym, nawet jeśli nie zostanie ponownie wyeksportowana.
mod foo {
struct Foo;
mod bar {
use super::Foo;
pub fn baz(foo: Foo) {}
}
}
prowadzi do
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
Jaki jest idiomatyczny sposób użycia pub
słowa kluczowego? Czy powinien być zarezerwowany dla rzeczy, które są faktycznie publiczne, czy może być używany do modułów wewnętrznych?
Odpowiedzi
Przyczyną niepowodzenia kompilacji Twojego przykładu jest ostatecznie to, że tak mówi RFC (136) . (Zobacz także numer 22261 )
Jakie ograniczenia dotyczą przedmiotów publicznych?
Zasady dotyczące różnego rodzaju pozycji publicznych są następujące:
- Jeżeli jest to
static
deklaracja, to pozycje, do których odnosi się jej typ, muszą być jawne.- Jeśli jest to
fn
deklaracja, elementy, do których odwołuje się jej zakres cech, typy argumentów i zwracany typ, muszą być publiczne.- Jeśli jest to deklaracja
struct
lubenum
, pozycje, do których odnosi się jej zakres cech i typy jejpub
pól, muszą być publiczne.- Jeżeli jest to
type
deklaracja, pozycje, o których mowa w jej definicji, muszą być jawne.- Jeśli jest to
trait
deklaracja, elementy, do których odwołuje się jej super-cechy, w granicach cechy parametrów jej typu oraz w sygnaturach jej metod (patrzfn
przypadek powyżej), muszą być publiczne.
Krótko mówiąc, baz
nie może być, pub
ponieważ ma argument, który jest typem prywatnym. Tak więc, jeśli baz
jest pub
to umożliwić rodzicom mod foo
do reeksportu baz
przez robi pub use bar::baz;
. Jest to oczywiście niedozwolone i to jest powód, dla którego przykład jako całość jest nielegalny.
Niektórzy wcześniej wspomnieli, że pub fn baz
powinno to być dozwolone i zamiast tego podawać błąd kompilacji w przypadku ponownego eksportu modułu nadrzędnego. Jednak wykrycie tego wymagałoby bardziej złożonej analizy statycznej, a ostatecznie nie zostało to zrobione, ponieważ dokument RFC zdefiniował, że jest to nielegalne.
pub
określa, że element jest dostępny dla modułu nadrzędnego. Jeśli wszyscy przodkowie modułów tak pub
, to ten element jest eksportowany przez skrzynię jako całość.
Słowo kluczowe
pub
umożliwia dostęp do dowolnego modułu, funkcji lub struktury danych z wnętrza modułów zewnętrznych. Słowapub
kluczowego można również użyć wuse
deklaracji, aby ponownie wyeksportować identyfikator z przestrzeni nazw.- Dokumentacja rdzy
Przy założeniu, że przedmiot jest publiczny lub prywatny, Rust umożliwia dostęp do elementu w dwóch przypadkach:
- Jeśli element jest publiczny, to można uzyskać do niego dostęp z zewnątrz z jakiegoś modułu m, jeśli masz dostęp do wszystkich modułów nadrzędnych elementu z m. Potencjalnie możesz również nazwać element poprzez ponowne eksportowanie. Zobacz poniżej.
- Jeśli element jest prywatny, może uzyskać do niego dostęp bieżący moduł i jego elementy podrzędne.
- Odniesienie do rdzy - Widoczność i prywatność