Apakah `pub` dimaksudkan untuk menunjukkan public-to-crate atau public-to-module? [duplikat]

Dec 15 2020

Untuk membuat metode dari submodul menjadi publik, Anda harus mengekspor ulang secara eksplisit atau jadikan submodul itu sendiri publik:

mod foo {
    mod bar {
        pub fn baz() {}
    }
    pub use self::bar::baz;
}

Ini sepertinya petunjuk yang pubdigunakan untuk menunjukkan sesuatu harus publik hanya untuk modul (karena Anda dapat memilih untuk tidak melakukan ini)

Tetapi jika Anda menggunakan tipe privat yang ditentukan dalam konteks luar, Anda mendapatkan kesalahan jika Anda mencoba dan membuat fungsi publik yang melibatkannya menjadi publik dalam konteks dalam bahkan ketika tidak diekspor ulang.

mod foo {
    struct Foo;

    mod bar {
        use super::Foo;

        pub fn baz(foo: Foo) {}
    }
}

menghasilkan

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

Apa cara idiomatik untuk menggunakan pubkata kunci? Haruskah itu disediakan untuk hal-hal yang sebenarnya publik atau dapatkah digunakan untuk modul internal?

Jawaban

2 vallentin Dec 15 2020 at 04:06

Alasan contoh Anda gagal untuk dikompilasi, pada akhirnya karena RFC (136) mengatakan demikian. (Lihat juga masalah 22261 )

Pembatasan apa yang berlaku untuk barang publik?

Aturan untuk berbagai jenis barang publik adalah sebagai berikut:

  • Jika itu adalah staticdeklarasi, barang yang dimaksud dalam tipenya harus publik.
  • Jika itu adalah fndeklarasi, item yang dirujuk dalam batas sifat, tipe argumen, dan tipe kembaliannya harus publik.
  • Jika itu adalah structatau enumdeklarasi, item yang dirujuk dalam batas sifatnya dan dalam jenis pubbidangnya harus publik.
  • Jika berupa typedeklarasi, barang yang dimaksud dalam definisinya harus publik.
  • Jika itu adalah sebuah traitdeklarasi, item yang dirujuk dalam super-traitsnya, dalam batasan sifat dari parameter tipenya, dan dalam tanda tangan metodenya (lihat fnkasus di atas) harus bersifat publik.

Singkatnya, baztidak diperbolehkan pubkarena memiliki argumen yang merupakan tipe pribadi. Jadi, jika bazini pubakan memungkinkan orang tua mod foountuk re-ekspor bazdengan melakukan pub use bar::baz;. Ini tentu saja tidak diperbolehkan, dan inilah alasan mengapa contoh secara keseluruhan ilegal.

Beberapa sebelumnya telah menyebutkan bahwa pub fn bazharus diizinkan, dan sebagai gantinya memberikan kesalahan kompilasi jika modul induk mengekspornya kembali. Namun, hal itu memerlukan analisis statis yang lebih kompleks untuk dideteksi, dan pada akhirnya belum dilakukan karena RFC menetapkan bahwa hal itu ilegal.


pubmenentukan bahwa item dapat diakses oleh modul induk. Jika semua leluhur modul adalah pub, maka item itu diekspor oleh peti secara keseluruhan.

Kata kunci pubmembuat modul, fungsi, atau struktur data apa pun dapat diakses dari dalam modul eksternal. Kata pubkunci juga dapat digunakan dalam usedeklarasi untuk mengekspor ulang pengenal dari namespace.

- Dokumentasi Rust

Dengan gagasan bahwa suatu item bersifat publik atau pribadi, Rust mengizinkan akses item dalam dua kasus:

  1. Jika sebuah item bersifat publik, maka ia dapat diakses secara eksternal dari beberapa modul m jika Anda dapat mengakses semua modul leluhur item tersebut dari m. Anda juga berpotensi dapat memberi nama item tersebut melalui ekspor ulang. Lihat di bawah.
  2. Jika sebuah item bersifat pribadi, ia dapat diakses oleh modul saat ini dan turunannya.

- Referensi Rust - Visibilitas dan Privasi