可視性とカプセル化
モジュール内のアイテムと同様に、struct のフィールドもデフォルトでは非公開です。非公開フィールドも同様に、そのモジュールの他の部分(子モジュールを含む)からは参照できます。これにより、struct の実装詳細をカプセル化し、外部から見えるデータや機能を制御できます。
// Copyright 2024 Google LLC // SPDX-License-Identifier: Apache-2.0 use outer::Foo; mod outer { pub struct Foo { pub val: i32, is_big: bool, } impl Foo { pub fn new(val: i32) -> Self { Self { val, is_big: val > 100 } } } pub mod inner { use super::Foo; pub fn print_foo(foo: &Foo) { println!("Is {} big? {}", foo.val, foo.is_big); } } } fn main() { let foo = Foo::new(42); println!("foo.val = {}", foo.val); // let foo = Foo { val: 42, is_big: true }; outer::inner::print_foo(&foo); // println!("Is {} big? {}", foo.val, foo.is_big); }
-
このスライドでは、struct における可視性がモジュール単位で決まることを示しています。オブジェクト指向言語に慣れた受講者は、型がカプセル化の境界であることに慣れているかもしれません。そのため、このスライドは Rust の振る舞いがそれとは異なることを示しつつ、それでもカプセル化を実現できることを示しています。
-
is_bigフィールドがFooによって完全に制御されている点に注目してください。これにより、Fooはその初期化方法を制御し、必要な不変条件(たとえば、val > 100の場合にのみis_bigがtrueになること)を強制できます。 -
型の非公開フィールドや非公開メソッドにアクセスするために、同じモジュール内(子モジュールを含む)でヘルパー関数を定義できることを指摘してください。
-
最初のコメントアウトされた行は、非公開フィールドを持つ struct を初期化できないことを示しています。2 つ目は、非公開フィールドに直接アクセスすることもできないことを示しています。
-
enumでは可視性を設定できません。バリアントと、そのバリアント内のデータは常に公開です。
さらに学ぶには
-
enumにおける可視性(あるいはその欠如)についてさらに知りたがる受講者がいれば、#[doc_hidden]と#[non_exhaustive]を取り上げ、それらがenumでできることをどのように制限するために使われるかを示せます。 -
他のモジュールに
implブロックがある場合でも、モジュールの可視性は引き続き適用されます(playground の例)。