可視性
デフォルトでは、モジュール内の要素はプライベートですが、これはpubで修飾することでパブリックな属性にすることができます。パブリックな属性のみがモジュールの外のスコープからアクセスできます。
// `my_mod`という名前のモジュール
mod my_mod {
// モジュール内の要素はデフォルトでプライベート。
fn private_function() {
println!("called `my_mod::private_function()`");
}
// `pub`を用いてパブリックに変更。
pub fn function() {
println!("called `my_mod::function()`");
}
// モジュール内からならば、プライベートな属性にアクセスできます。
pub fn indirect_access() {
print!("called `my_mod::indirect_access()`, that\n> ");
private_function();
}
// モジュールもネストできます。
pub mod nested {
pub fn function() {
println!("called `my_mod::nested::function()`");
}
#[allow(dead_code)]
fn private_function() {
println!("called `my_mod::nested::private_function()`");
}
// `pub(in path)`形式で宣言された関数は該当のパス内でのみアクセスできます。
// `path`は親や先祖のモジュールでなくてはなりません。
pub(in crate::my_mod) fn public_function_in_my_mod() {
print!("called `my_mod::nested::public_function_in_my_mod()`, that\n> ");
public_function_in_nested();
}
// `pub(self)`形式で宣言された関数は現在のモジュール内でのみアクセスできます。
// つまり、プライベートにするのと同じです。
pub(self) fn public_function_in_nested() {
println!("called `my_mod::nested::public_function_in_nested()`");
}
// `pub(super)`形式で宣言された関数は親モジュール内でのみアクセスできます。
pub(super) fn public_function_in_super_mod() {
println!("called `my_mod::nested::public_function_in_super_mod()`");
}
}
pub fn call_public_function_in_my_mod() {
print!("called `my_mod::call_public_function_in_my_mod()`, that\n> ");
nested::public_function_in_my_mod();
print!("> ");
nested::public_function_in_super_mod();
}
// pub(crate)により関数は現在のクレート内でのみアクセスできます。
pub(crate) fn public_function_in_crate() {
println!("called `my_mod::public_function_in_crate()`");
}
// ネストしたモジュールも、同様の性質を示します。
mod private_nested {
#[allow(dead_code)]
pub fn function() {
println!("called `my_mod::private_nested::function()`");
}
// 親がプライベートな場合、子要素がより大きなスコープでアクセスできるように宣言されていても、
// 子要素にアクセス可能な範囲は制限されます。
#[allow(dead_code)]
pub(crate) fn restricted_function() {
println!("called `my_mod::private_nested::restricted_function()`");
}
}
}
fn function() {
println!("called `function()`");
}
fn main() {
// モジュールによって、同名の関数を区別することができます。
function();
my_mod::function();
// パブリックな要素ならば、たとえネストしたものでも、
// モジュールの外からアクセスすることができます。
my_mod::indirect_access();
my_mod::nested::function();
my_mod::call_public_function_in_my_mod();
// pub(crate)の要素は同じクレートのどこからでも呼び出すことができます。
my_mod::public_function_in_crate();
// pub(in path)の要素は指定されたモジュールからのみ呼び出すことができます。
// エラー!`public_function_in_my_mod`関数はプライベート。
//my_mod::nested::public_function_in_my_mod();
// TODO ^ 試しにこの行をアンコメントしてみましょう。
// プライベートな要素は、たとえパブリックなモジュール内に存在していても
// 直接アクセスすることはできません。
// エラー!`private_function`はプライベート。
//my_mod::private_function();
// TODO ^ 試しにこの行をアンコメントしてみましょう。
// エラー!`private_function`はプライベート。
//my_mod::nested::private_function();
// TODO ^ 試しにこの行をアンコメントしてみましょう。
// エラー!`private_nested`はプライベートなモジュール。
//my_mod::private_nested::function();
// TODO ^ 試しにこの行をアンコメントしてみましょう。
// エラー!`private_nested`はプライベートなモジュール。
//my_mod::private_nested::restricted_function();
// TODO ^ 試しにこの行をアンコメントしてみましょう。
}