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)
を使用したならば、それはそのライブラリの中でのみ使用され、ライブラリを使う方々には非公開という状態になります。何かしら大きなアプリケーションやライブラリを作成・公開しようとお考えの場合は結構重要なものかもしれません。