Soll "Pub" "Public-to-Crate" oder "Public-to-Module" anzeigen? [Duplikat]
Um Methoden aus einem Submodul öffentlich zu machen, müssen Sie sie explizit erneut exportieren oder das Submodul selbst öffentlich machen:
mod foo {
mod bar {
pub fn baz() {}
}
pub use self::bar::baz;
}
Dies scheint darauf pub
hinzudeuten, dass verwendet wird, um anzuzeigen, dass eine Sache nur für ein Modul öffentlich sein sollte (da Sie sich dafür entscheiden können, dies nicht zu tun).
Wenn Sie jedoch einen im äußeren Kontext definierten privaten Typ verwenden, wird eine Fehlermeldung angezeigt, wenn Sie versuchen, eine öffentliche Funktion, die ihn einbezieht, im inneren Kontext öffentlich zu machen, auch wenn sie nicht erneut exportiert wird.
mod foo {
struct Foo;
mod bar {
use super::Foo;
pub fn baz(foo: Foo) {}
}
}
führt zu
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
Was ist die idiomatische Art, das pub
Schlüsselwort zu verwenden? Sollte es für Dinge reserviert sein, die tatsächlich öffentlich sind, oder kann es für interne Module verwendet werden?
Antworten
Der Grund, warum Ihr Beispiel nicht kompiliert werden kann, liegt letztendlich darin, dass der RFC (136) dies gesagt hat. (Siehe auch Ausgabe 22261 )
Welche Einschränkungen gelten für öffentliche Gegenstände?
Die Regeln für verschiedene Arten von öffentlichen Gegenständen lauten wie folgt:
- Wenn es sich um eine
static
Deklaration handelt, müssen die in ihrem Typ genannten Elemente öffentlich sein.- Wenn es sich um eine
fn
Deklaration handelt, müssen Elemente, auf die in den Merkmalsgrenzen, Argumenttypen und Rückgabetypen verwiesen wird, öffentlich sein.- Wenn es sich um eine
struct
oder eineenum
Deklaration handelt, müssen Elemente, auf die in ihren Merkmalsgrenzen und in den Arten ihrerpub
Felder Bezug genommen wird, öffentlich sein.- Wenn es sich um eine
type
Erklärung handelt, müssen die in ihrer Definition genannten Elemente öffentlich sein.- Wenn es sich um eine
trait
Deklaration handelt, müssen Elemente, auf die in ihren Supermerkmalen, in den Merkmalsgrenzen ihrer Typparameter und in den Signaturen ihrer Methoden (siehefn
Fall oben) Bezug genommen wird, öffentlich sein.
Kurz gesagt, baz
darf nicht sein, pub
weil es ein Argument hat, das ein privater Typ ist. Wenn also baz
ist pub
es die Eltern erlauben würde , mod foo
auf die Wiederausfuhr baz
von tun pub use bar::baz;
. Dies ist natürlich nicht erlaubt, und dies ist der Grund, warum das Beispiel als Ganzes illegal ist.
Einige haben bereits erwähnt, dass pub fn baz
dies zulässig sein sollte und stattdessen ein Kompilierungsfehler für den Fall ausgegeben werden sollte, dass das übergeordnete Modul ihn erneut exportiert. Dies würde jedoch eine komplexere statische Analyse erfordern, um sie zu erkennen, und wurde letztendlich nicht durchgeführt, da der RFC definiert hat, dass dies illegal ist.
pub
Gibt an, dass das übergeordnete Modul auf das Element zugreifen kann. Wenn alle Modulvorfahren vorhanden sind pub
, wird dieses Element von der gesamten Kiste exportiert.
Das Schlüsselwort
pub
macht jedes Modul, jede Funktion oder Datenstruktur von innerhalb externer Module aus zugänglich. Daspub
Schlüsselwort kann auch in eineruse
Deklaration verwendet werden, um einen Bezeichner aus einem Namespace erneut zu exportieren.- Rostdokumentation
Mit der Vorstellung, dass ein Gegenstand entweder öffentlich oder privat ist, erlaubt Rust in zwei Fällen den Zugang zu Gegenständen:
- Wenn ein Element öffentlich ist, kann von einem Modul m aus extern darauf zugegriffen werden, wenn Sie von m aus auf alle Vorgängermodule des Elements zugreifen können. Möglicherweise können Sie den Artikel auch durch Reexporte benennen. Siehe unten.
- Wenn ein Element privat ist, kann das aktuelle Modul und seine Nachkommen darauf zugreifen.
- Die Rostreferenz - Sichtbarkeit und Datenschutz