Menu
Coddy logo textTech

まとめ - ジェネリックなプリンター

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

challenge icon

チャレンジ

簡単

trait bound の力を示す柔軟なアナウンスシステムを作りましょう!Printable trait と、この trait を Implement する any type を announce できる generic function を作成します。これにより、generics と traits がどのように連携して、再利用可能で type-safe な code を実現するかを確認できます。

code を2つのファイルに分けて整理します。

  • printable.rs:public な Printable trait を Define します。この trait には、&self を takes し、String を returns する print_info method を定義します。次に、Printable を Implement する any type T を受け取る、announce という public generic function を作成します。この function は、item に対して print_info() を呼び出した result である {info} を使って、Announcement: {info} を print する必要があります。
  • main.rsPrintable を Implement する2つの public struct を作成します。
    • Person:public な name field(String)を持ちます。その print_infoPerson: {name} を return する必要があります。
    • Product:public な name(String)と price(f64)fields を持ちます。その print_infoProduct: {name} - ${price} を return する必要があります。
    printable module を取り込み、inputs を使って Person と Product を作成し、それぞれに対して announce を呼び出して、generic function が any Printable type で動作することを示します。

この設計の利点は、announce が Person、Product、または将来追加される any type のどれを受け取るかを気にしないことです。type が print_info() を通じて情報を提供できることだけが必要です。trait bound によって、これが compile time に保証されます。

output には両方の announcement が表示されます。

Announcement: Person: {name}
Announcement: Product: {product_name} - ${price}

たとえば、inputs が AliceLaptop999.99 の場合:

Announcement: Person: Alice
Announcement: Product: Laptop - $999.99

3つの inputs を受け取ります。person の name、product の name、そして product の price です(f64 として parse します)。

自分で試してみよう

mod printable;

use printable::{Printable, announce};

// TODO: 公開の name フィールド (String) を持つ公開構造体 Person を定義する
// Person に Printable トレイトを実装する
// print_info は "Person: {name}" を返すべき

// TODO: 公開の name (String) と price (f64) フィールドを持つ公開構造体 Product を定義する
// Product に Printable トレイトを実装する
// print_info は "Product: {name} - ${price}" を返すべき

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

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

    let mut price_input = String::new();
    std::io::stdin().read_line(&mut price_input).expect("Failed to read line");
    let price: f64 = price_input.trim().parse().expect("Failed to parse price");

    // TODO: person_name で Person インスタンスを作成する

    // TODO: product_name と price で Product インスタンスを作成する

    // TODO: Person で announce を呼び出す

    // TODO: Product で announce を呼び出す
}

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

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