Menu
Coddy logo textTech

ジェネリックメソッド

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

ジェネリック構造体は任意の型を保持できますが、そのデータを操作するメソッドがなければ、あまり便利ではありません。ジェネリック構造体のメソッドを定義するには、implブロック内で特別な構文を使用する必要があります。

重要なのは、impl自体でジェネリックパラメータを宣言することです:

struct Wrapper<T> {
    value: T,
}

impl<T> Wrapper<T> {
    fn get(&self) -> &T {
        &self.value
    }
}

Wrapper<T> の前にある impl<T> に注目してください。これは、T が実装ブロック全体に対するジェネリック型パラメータであることを Rust に伝えます。この宣言がないと、Rust は T という具象型を探しますが、見つけられずに失敗します。

getメソッドは&Tを返します。これは、ラッパーが保持している任意の型への参照です。Tが整数、文字列、その他の型のいずれであっても機能します。

let num_wrapper = Wrapper { value: 100 };
let text_wrapper = Wrapper { value: "Rust" };

println!("{}", num_wrapper.get());  // 100
println!("{}", text_wrapper.get()); // Rust

ジェネリックなTがコンパイル時にそれぞれの具体的な型に適応するため、同じメソッド定義が両方に対して機能します。

challenge icon

チャレンジ

簡単

ジェネリックコンテナをメソッド付きに拡張しましょう!任意の型を保持でき、その contents とやり取りするためのメソッドを提供する Box 構造体(Rust の標準の Box と混同しないでください)を作成します。

コードを 2 つのファイルに整理します。

  • mybox.rs: private な field contents(型 T)を持つ public な generic struct called MyBox<T> を Define します。この struct に methods を Implement します。
    • given value で新しい MyBox を Creates する new associated function
    • contents への reference を返す(&self を使用)peek method
    • 新しい value を受け取り、current contents を Replace する(&mut self を使用)replace method
  • main.rs: module を取り込み、異なる型で generic methods が動作することを示します。box を作成し、その contents を peek し、values を replace して methods の動作を示します。

generic struct に methods を Implement するための key syntax を Remember してください。Rust に T が entire implementation block の generic parameter であることを伝えるため、MyBox<T> の前に impl<T> が必要です。

main file では、次の操作で MyBox を示します。

  1. integer で box を作成する(first input、i32 として parse)
  2. その contents を peek して value を print する
  3. contents を新しい integer で Replace する(second input、i32 として parse)
  4. もう一度 peek して updated value を示す
  5. string で second box を作成する(third input)
  6. string box の contents を peek する

output は次の format に従ってください。

Integer box contains: {value}
After replace: {value}
String box contains: {value}

たとえば、inputs が 1025Rust の場合:

Integer box contains: 10
After replace: 25
String box contains: Rust

3 つの inputs を受け取ります。initial integer、replacement integer、そして string value です。

自分で試してみよう

mod mybox;

use mybox::MyBox;

fn main() {
    // 入力を読み取る
    let mut input1 = String::new();
    std::io::stdin().read_line(&mut input1).expect("Failed to read line");
    let initial_int: i32 = input1.trim().parse().expect("Invalid integer");

    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let replacement_int: i32 = input2.trim().parse().expect("Invalid integer");

    let mut input3 = String::new();
    std::io::stdin().read_line(&mut input3).expect("Failed to read line");
    let string_value = input3.trim().to_string();

    // TODO: 初期整数で MyBox を作成する
    
    // TODO: Peek at its contents and print: "Integer box contains: {value}"
    
    // TODO: 内容を置換整数で置き換える
    
    // TODO: Peek again and print: "After replace: {value}"
    
    // TODO: 文字列値で2つ目の MyBox を作成する
    
    // TODO: Peek at the string box and print: "String box contains: {value}"
}
quiz icon腕試し

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

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

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