## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# 可視性

デフォルトでは、モジュール内の要素はプライベートですが、これは`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 ^ 試しにこの行をアンコメントしてみましょう。
    }