Menu
Coddy logo textTech

プライベートフィールド

CoddyのRustジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 10/61。

前のレッスンでは、struct、そのフィールド、そしてそのメソッドをすべて public にしました。しかし、真のカプセル化とは、データをどのように access できるかを制御することです。Rust では、フィールドを private にしたまま、struct を public にできます。

負の balance を決して持たない Wallet を考えてみましょう。fieldpublic なら、誰でも任意の値を設定できてしまいます。

// wallet.rs
pub struct Wallet {
    balance: f64,  // No pub = private!
}

impl Wallet {
    pub fn new(initial: f64) -> Wallet {
        Wallet { balance: initial }
    }
}

Wallet は public ですが、balance には pub キーワードがありません。つまり、モジュール外のコードでは constructor を使って Wallet を作成できますが、balance field を直接 read したり変更したりすることはできません。

// main.rs
mod wallet;
use wallet::Wallet;

fn main() {
    let w = Wallet::new(100.0);
    // println!("{}", w.balance);  // Error! フィールドはプライベートです
    // w.balance = -50.0;          // Error! プライベートフィールドにアクセスできません
}

これはカプセル化の基盤です。struct は自身のデータを管理します。外部コードは、あなたが提供するメソッドを経由しなければなりません。つまり、検証、ロギング、その他のロジックを追加できます。データは無効な状態から保護されたままになります。

これからのレッスンでは、getterメソッドとsetterメソッドを通じて、このprivateデータへの制御されたaccessを提供する方法を学びます。

challenge icon

チャレンジ

簡単

モジュール内で機密データを保護することでカプセル化を示す、温度センサーシステムを構築しましょう。

コードを整理するために、2つのファイルを作成します。

  • sensor.rs: 2つのfield、location(String)とreading(f64)を持つTemperatureSensor structをDefineします。structは他のファイルから使用できるようにpublicにしますが、両方のfieldはprivateのままにします。外部コードからセンサーのデータに直接accessしたり変更したりできないようにするためです。location nameとinitial temperature readingをTakesするpublicなnew constructorを追加します。
  • main.rs: sensor moduleを読み込み、constructorをusingしてTemperatureSensorを作成します。fieldはprivateなので直接printingすることはできません。代わりに、sensorが正常にcreatedされたことを示すconfirmation messageをprintingします。

このchallengeでは、private fieldのcore conceptに焦点を当てます。structにはaccessできますが、その内部データは保護されています。外部コードは、提供されたmethod(この場合はconstructorのみ)を通じてのみsensorとやり取りできます。

出力は次のexact formatに従う必要があります。

Sensor created for: {location}

printingのためにlocationにaccessするには、field自体がprivateなので、sensorをreturnする前にnew functionでこのmessageをprintingする必要があります。

たとえば、location "Kitchen"、reading 22.5でsensorを作成すると、出力は次のようになります。

Sensor created for: Kitchen

2つの入力を受け取ります。location nameとinitial temperature readingです。

REQUIRED OUTPUT FORMAT: [Your translated content here]

自分で試してみよう

mod sensor;

use sensor::TemperatureSensor;

fn main() {
    // 入力を読み取る
    let mut location = String::new();
    std::io::stdin().read_line(&mut location).expect("Failed to read line");
    let location = location.trim().to_string();
    
    let mut reading_str = String::new();
    std::io::stdin().read_line(&mut reading_str).expect("Failed to read line");
    let reading: f64 = reading_str.trim().parse().expect("Failed to parse reading");
    
    // TODO: コンストラクタを使用してTemperatureSensorを作成する
    // new関数が確認メッセージの出力を処理します
    
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Rustオンラインコンパイラ