Menu
Coddy logo textTech

ミュータブルなメソッド

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

メソッドは、データを読み取るだけでなく、さらに多くの処理を行う必要がある場合があります。データを変更する必要があるのです、構造体のフィールドを変更できるメソッドを作成するには、&mut self&selfの代わりに使用します。

mutキーワードは可変借用を示し、メソッドにインスタンスの内部状態を変更する権限を与えます。

struct Counter {
    value: i32,
}

impl Counter {
    fn increment(&mut self) {
        self.value += 1;
    }
    
    fn decrement(&mut self) {
        self.value -= 1;
    }
    
    fn get(&self) -> i32 {
        self.value
    }
}

incrementdecrementvalue を変更するため &mut self を使用し、一方 get はデータを読み取るだけなので &self を使用していることに注目してください。

可変メソッドを呼び出すときは、インスタンス自体を可変として宣言する必要があります。

fn main() {
    let mut counter = Counter { value: 0 };
    
    counter.increment();
    counter.increment();
    println!("{}", counter.get()); // 2
    
    counter.decrement();
    println!("{}", counter.get()); // 1
}

インスタンスを作成するときに mut キーワードを忘れると、Rust はそのインスタンスに対して &mut self メソッドを呼び出すことを禁止します。これにより、データが変更される可能性があるときに、常にそれを把握できます。

challenge icon

チャレンジ

簡単

balance という単一のフィールドを持つ BankAccount 構造体を作成してください(i32)。

BankAccount の implementation ブロックを追加し、3つのメソッドを定義してください。

  • deposit&mut selfamount: i32 を受け取り、amount を残高に加算します
  • withdraw&mut selfamount: i32 を受け取り、amount を残高から減算します
  • get_balance&self を受け取り、現在の残高を i32 として返します

3つの入力を受け取ります。

  • 1行目:初期残高(i32)
  • 2行目:入金額(i32)
  • 3行目:引き出し額(i32)

初期残高を使って可変の BankAccount インスタンスを作成し、指定された金額を入金してから、指定された金額を引き出し、最終的な残高を出力してください。

期待される出力形式:

{final_balance}

自分で試してみよう

use std::io;

// TODO: ここに BankAccount 構造体を定義する


// TODO: deposit、withdraw、get_balance メソッドを持つ BankAccount の実装ブロックを追加する


fn main() {
    let mut input = String::new();
    
    // 初期残高を読み取る
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let initial_balance: i32 = input.trim().parse().expect("Invalid number");
    
    input.clear();
    
    // 入金額を読み取る
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let deposit_amount: i32 = input.trim().parse().expect("Invalid number");
    
    input.clear();
    
    // 出金額を読み取る
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let withdraw_amount: i32 = input.trim().parse().expect("Invalid number");
    
    // TODO: initial_balance で可変の BankAccount インスタンスを作成する
    // TODO: deposit_amount で deposit を呼び出す
    // TODO: withdraw_amount で withdraw を呼び出す
    // TODO: get_balance を使って最終残高を出力する
}
quiz icon腕試し

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

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

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