Rustでは、アクセス修飾子(pub、pub(crate)、pub(super))は、データや関数への明確なアクセス制御のメカニズムとして登場しました。これはC言語には欠けていたものです。アイデアは、モジュールの要素の可視性を制限し、ライブラリのユーザーに本当に必要なものだけを提供することです。
主な難しさは、構造体自体が公開(pub)として宣言されていても、そのフィールドがデフォルトでプライベートのままであることです。また、ネストされた構造体やモジュールへのアクセスを適切に整理し、カプセル化を壊さず、APIが「穴だらけ」になったり、逆にあまりにも閉じすぎたりしないようにすることがよく問題になります。
構造体のフィールドに対してアクセス修飾子を個別に指定する必要があります。自動生成される構造体や格納型を設計する際には、どの部分を公開し、どの部分を隠すべきかを慎重に考える必要があります。これはAPIとコードアーキテクチャの重要な部分です。
コード例:
mod outer { pub struct Exposed { pub field: i32, hidden: bool, } } // "field"フィールドは使用可能ですが、 // hiddenは使用できません。 let e = outer::Exposed { field: 42, hidden: true }; println!("{}", e.field); // e.hidden // コンパイルエラー
主な特徴:
公開(pub)として宣言された構造体は、現在のモジュールの外で完全にアクセスできないことがありますか?
はい、すべてのフィールドがプライベートのままであれば、構造体は名前だけで公開され、モジュールの外でインスタンスを作成または初期化することはできません。
構造体のプライベートフィールドは、継承や他の方法でアクセスできるようになりますか?
いいえ、RustにはOOP言語のような従来の継承はありません。プライベートフィールドへのアクセスはモジュールによって制御され、大幅に制限されています。
公開フィールドを持つ構造体を、プライベートなモジュールで宣言した場合はどうなりますか?
構造体とそのフィールドは親モジュールの外で見えなくなります。修飾子は親モジュールのスコープを超えることはありません。
** ネガティブケース
ユーザーは構造体をpubとして宣言したが、すべてのフィールドがプライベートのままであった。その結果、外部コードは構造体を適切に使用できず、インスタンスを作成することも、値を取得することもできませんでした。
利点:
欠点:
** ポジティブケース
ユーザーは、必要なフィールドのみをpubで公開し、セキュリティ上の詳細はプライベートのままにしました。アクセスにはゲッター/セッターを使用します。
利点:
欠点: