Rustの可視性制御を復習する

f:id:ironoir:20210131121425p:plain

全人類は以下を読もう。以上。

doc.rust-lang.org

と言いたいところだけど、ポイントだけ。

With the notion of an item being either public or private, Rust allows item accesses in two cases:

  1. f an item is public, then it can be accessed externally from some module m if you can access all the item's ancestor modules from m. You can also potentially be able to name the item through re-exports. See below.
  2. If an item is private, it may be accessed by the current module and its descendants.

2つの原則がある。

  1. アクセス元からアクセス先までの経路が全部publicじゃないとアクセス不可
  2. privateでも、カレントモジュールとその祖先はアクセス可能

1つ目に書いてある「再エクスポート」については今は触れません。2についてはずいぶん前にこのブログでも触れたことありましたね。

ironoir.hatenablog.com

1はわかりやすい原則なのであまり間違えなさそうですが、一応例を示しておきます。a_1a_2のモジュールはprivateなので、その中で例えpub(crate)という広い可視性を付けようとしても阻まれてしまうわけです。

mod a {
    mod a_1 {
        pub struct A_1_struct {}
    }
    mod a_2 {
        pub(crate) struct A_2_struct {}
    }
    fn func_a() {
        a_1::A_1_struct; // NG!
        a_2::A_2_struct; // NG!
    } 
}

pubも種類があるが、すべてpub(in ...)で置き換えられます。inで指定されたpathとそのサブモジュール全てがpubになる、というルールです。

  • pub = pub(self) = pub(in self)
  • pub(super) = pub(in super)

というか、pub(self) はいつ使うんだよ、と一瞬思いましたが、マクロとかでコード生成時に可視性を制御するのに使えるかな、と。いやでも、pub(in ...)があれば事足りませんか?なんでだろう。。。求む情報。