Soll "Pub" "Public-to-Crate" oder "Public-to-Module" anzeigen? [Duplikat]

Dec 15 2020

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 pubhinzudeuten, 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 pubSchlü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

2 vallentin Dec 15 2020 at 04:06

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 staticDeklaration handelt, müssen die in ihrem Typ genannten Elemente öffentlich sein.
  • Wenn es sich um eine fnDeklaration handelt, müssen Elemente, auf die in den Merkmalsgrenzen, Argumenttypen und Rückgabetypen verwiesen wird, öffentlich sein.
  • Wenn es sich um eine structoder eine enumDeklaration handelt, müssen Elemente, auf die in ihren Merkmalsgrenzen und in den Arten ihrer pubFelder Bezug genommen wird, öffentlich sein.
  • Wenn es sich um eine typeErklärung handelt, müssen die in ihrer Definition genannten Elemente öffentlich sein.
  • Wenn es sich um eine traitDeklaration handelt, müssen Elemente, auf die in ihren Supermerkmalen, in den Merkmalsgrenzen ihrer Typparameter und in den Signaturen ihrer Methoden (siehe fnFall oben) Bezug genommen wird, öffentlich sein.

Kurz gesagt, bazdarf nicht sein, pubweil es ein Argument hat, das ein privater Typ ist. Wenn also bazist pubes die Eltern erlauben würde , mod fooauf die Wiederausfuhr bazvon 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 bazdies 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.


pubGibt 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 pubmacht jedes Modul, jede Funktion oder Datenstruktur von innerhalb externer Module aus zugänglich. Das pubSchlüsselwort kann auch in einer useDeklaration 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:

  1. 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.
  2. Wenn ein Element privat ist, kann das aktuelle Modul und seine Nachkommen darauf zugreifen.

- Die Rostreferenz - Sichtbarkeit und Datenschutz