pubキーワード
C++やjavaなどではpublicやprivateやprotectedなどのキーワードを付けることで、公開範囲を決定することができますが、Rustではシンプルにpubキーワードのみとなっています。その代わり、pub(..)といったかたちで範囲を変更することができます。最初に非公開の構造体の例を挙げます。今回は便宜上同一ファイル内にすべて書いています。モジュール
aには、構造体Aがあります。この構造体は見やすくするためにユニット構造体(フィールドなし)にしています。
mod a {
struct A;
}
fn main() {
let x = a::A; // ERROR
}
これはpubがついていない構造体なので、モジュールa内でのみ有効なものとなり、当然エラーとなります。namespace、名前空間、package、blockなど、言語のよって呼び名や仕様は様々ですが、要は使える範囲のことでスコープといい、Rustでも同じようにそういったものがあります。モジュールもその一つです。
公開にしたい場合は
pub struct A;としなければなりません。例えばこの構造体がA {x: i32, y: i32}というように、いくつかフィールドを持っているならば、それらについてもpubで公開範囲を指定できます。では以下の場合はどうでしょうか?
mod a {
pub(self) struct A;
}
fn main() {
let x = a::A; // ERROR
}
pubがついていますが、さらに(self)と続いています。この場合、公開範囲は
mod a自身(self)となります。つまりmod aの外には公開していないということになりますので、最初の例の時と同様のエラーとなります。では以下のような場合はどうなるでしょうか?
mod a {
pub mod aa {
pub(super) struct A;
}
}
fn main() {
let x = a::aa::A; // ERROR
}
今回はmod aの中にパブリックなmod aaがあり、その中にpub(super) struct A;とあります。この場合、
mod aa自体は完全に公開となっていますので、どこででも使えますが、構造体Aは公開範囲はsuperとあるので、その親にあたるmod a内となります。したがって、mod aa自体は完全に公開されているものの、肝心の中身はmod aの中でしか使えないということで、この場合も最初の例と同様エラーとなります。pubキーワードの後には、他にも(crate)や(in path)などがあります。pub(in self)はpub(self)と等価、pub(in super)はpub(super)と等価です。例えば自作ライブラリの中で、
pub(crate)を使用したならば、それはそのライブラリの中でのみ使用され、ライブラリを使う方々には非公開という状態になります。何かしら大きなアプリケーションやライブラリを作成・公開しようとお考えの場合は結構重要なものかもしれません。