まとめ - ジェネリックなプリンター
CoddyのRustジャーニー「Object Oriented Programming」セクションの一部 — レッスン 44/61。
チャレンジ
簡単トレイト境界の威力を示す、柔軟なアナウンスシステムを構築しましょう!Printableトレイトと、このトレイトを実装するあらゆる型をアナウンスできるジェネリック関数を作成します。これにより、ジェネリクスとトレイトがどのように連携して、再利用可能で型安全なコードを作成するかを学びます。
コードは2つのファイルに分けて構成します:
printable.rs:&selfを受け取りStringを返すprint_infoメソッドを持つ、パブリックなPrintableトレイトを定義します。次に、Printableを実装する任意の型Tを受け取る、announceというパブリックなジェネリック関数を作成します。この関数は、Announcement: {info}と出力する必要があります。ここで{info}は、そのアイテムに対してprint_info()を呼び出した結果です。main.rs:Printableを実装する2つのパブリックな構造体を作成します:Person— パブリックなnameフィールド(String)を持ちます。そのprint_infoは"Person: {}"の形式でPerson: {name}を返す必要があります。Product— パブリックなname(String)とprice(f64)フィールドを持ちます。そのprint_infoは"Product: {} - ${}"の形式でProduct: {name} - ${price}を返す必要があります。
announceを呼び出して、ジェネリック関数が任意のPrintable型で動作することを確認してください。
この設計の素晴らしい点は、announceがPersonを受け取るか、Productを受け取るか、あるいは将来定義される他の型を受け取るかを気にしないことです。型がprint_info()を通じて情報を提供できることだけを要求します。トレイト境界は、これをコンパイル時に保証します。
出力には両方のアナウンスが表示されるはずです:
Announcement: Person: {name}
Announcement: Product: {product_name} - ${price}例えば、入力がAlice、Laptop、999.99の場合:
Announcement: Person: Alice
Announcement: Product: Laptop - $999.993つの入力を受け取ります:人物の名前、製品名、および製品の価格(f64としてパースしてください)。
自分で試してみよう
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 を呼び出します
}