Menu
Coddy logo textTech

メソッドチェーン

CoddyのRustジャーニー「Object Oriented Programming」セクションの一部 — レッスン 6/61。

これまで、ミュータブルなメソッドは構造体を変更し、何も返しませんでした。しかし、同じインスタンスに対して複数のメソッドを連続して呼び出したい場合はどうすればよいでしょうか?self への参照を返すことで、メソッドチェーンが可能になります。これは、複数のメソッド呼び出しを1つの式の中で繋げて記述するパターンです。

重要なのは、&mut self メソッドが &mut Self を返すようにすることです:

struct Config {
    debug: bool,
    timeout: u32,
}

impl Config {
    fn new() -> Config {
        Config { debug: false, timeout: 30 }
    }
    
    fn set_debug(&mut self, value: bool) -> &mut Self {
        self.debug = value;
        self
    }
    
    fn set_timeout(&mut self, seconds: u32) -> &mut Self {
        self.timeout = seconds;
        self
    }
}

各メソッドは構造体を変更し、その後 self(同じインスタンスへの可変参照)を返します。これにより、次のメソッド呼び出しでそのインスタンスに対してすぐに作業を継続できるようになります:

fn main() {
    let mut config = Config::new();
    
    config.set_debug(true).set_timeout(60);
    
    println!("Debug: {}, Timeout: {}", config.debug, config.timeout);
    // 出力: Debug: true, Timeout: 60
}

3つの個別のステートメントを記述する代わりに、すべてを1つの流れるような行で構成します。この「ビルダースタイル」パターンは、多くのオプション設定を持つオブジェクトをセットアップする際に特に有用で、コードをより簡潔で読みやすくします。

challenge icon

チャレンジ

簡単

3つのフィールド、bold (bool)、italic (bool)、および size (u32) を持つ TextStyle 構造体を作成してください。

TextStyle に以下の内容を含む実装ブロックを追加してください:

  • newboldfalseitalicfalsesize12 に設定した TextStyle を返す関連関数
  • set_bold&mut selfbool 値を受け取り、bold フィールドを設定し、メソッドチェーンのために &mut Self を返すメソッド
  • set_italic&mut selfbool 値を受け取り、italic フィールドを設定し、メソッドチェーンのために &mut Self を返すメソッド
  • set_size&mut selfu32 値を受け取り、size フィールドを設定し、メソッドチェーンのために &mut Self を返すメソッド

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

  • 1行目:bold の設定 (true または false)
  • 2行目:italic の設定 (true または false)
  • 3行目:フォントサイズ (u32)

new を使用して可変の TextStyle を作成し、メソッドチェーンを使用して1つの式ですべての3つの設定を適用してください。最終的な状態を以下の形式で出力してください。

期待される出力形式:

Bold: {bold}, Italic: {italic}, Size: {size}

チートシート

&mut self を受け取るメソッドは、メソッドチェーンを可能にするために &mut Self を返すことができます:

impl Config {
    fn set_debug(&mut self, value: bool) -> &mut Self {
        self.debug = value;
        self
    }
    
    fn set_timeout(&mut self, seconds: u32) -> &mut Self {
        self.timeout = seconds;
        self
    }
}

これにより、単一の式で複数のメソッド呼び出しが可能になります:

let mut config = Config::new();
config.set_debug(true).set_timeout(60);

各メソッドは構造体を変更し、同じインスタンスへの可変の参照を返します。これにより、次のメソッドがすぐにそのインスタンスに対して操作を継続できるようになります。

自分で試してみよう

use std::io;

// TODO: ここで TextStyle 構造体を定義します


// TODO: TextStyle の実装ブロックを追加します。以下の内容を含めてください:
// - new() 関連関数
// - set_bold() メソッド
// - set_italic() メソッド
// - set_size() メソッド


fn main() {
    let mut input = String::new();
    
    // 太字設定を読み込む
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let bold: bool = input.trim().parse().expect("Invalid bool");
    input.clear();
    
    // 斜体設定を読み込む
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let italic: bool = input.trim().parse().expect("Invalid bool");
    input.clear();
    
    // サイズ設定を読み込む
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let size: u32 = input.trim().parse().expect("Invalid u32");
    
    // TODO: new() を使用して可変の TextStyle を作成し、メソッドチェーンを使用して
    // 3つの設定すべてを単一の式で適用します
    
    
    // TODO: 次の形式で結果を出力します: Bold: {bold}, Italic: {italic}, Size: {size}
    
}
quiz icon腕試し

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

Object Oriented Programmingのすべてのレッスン