Display トレイト
CoddyのRustジャーニー「Object Oriented Programming」セクションの一部 — レッスン 36/61。
Debugは開発者がデータを検査するのには最適ですが、Displayトレイトはユーザー向けの出力のために設計されています。これはprintln!内の{}フォーマッタを支えるものです。Debugとは異なり、RustはDisplayを自動的にderiveすることはできません。手動で実装する必要があります。
Display を実装するには、fmt モジュールを取り込み、fmt メソッドを実装する必要があります:
use std::fmt;
struct Temperature {
celsius: f64,
}
impl fmt::Display for Temperature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}°C", self.celsius)
}
}
fmtメソッドはFormatterを受け取り、fmt::Resultを返します。write!マクロを使用して出力をフォーマットし、selfを通じて構造体のフィールドにアクセスします。
これで、標準の {} フォーマッタを使用して構造体を出力できるようになりました:
let temp = Temperature { celsius: 23.5 };
println!("{}", temp); // 23.5°C
主な違い:Debug出力はデータの構造を表示し(デバッグに役立ちます)、一方でDisplay出力は洗練されており、エンドユーザー向けです。構造体は両方を実装できます。デバッグには{:?}を、クリーンな出力には{}を使用します。
チャレンジ
簡単ユーザーフレンドリーな製品表示システムを作成しましょう!Debug はデータの生の構造を表示しますが、Display トレイトを使用すると、エンドユーザーに最適な、洗練された人間が読みやすい出力を構築できます。
コードを2つのファイルに分けて構成します:
product.rs: 2つのパブリックフィールドname(String) とprice(f64) を持つパブリックなProduct構造体を定義します。この構造体にDisplayトレイトを実装し、{name} - ${price}という形式でフォーマットされるようにします。std::fmtをインポートし、fmtメソッド内でwrite!マクロを使用することを忘れないでください。main.rs: product モジュールを取り込み、提供された入力を使用してProductインスタンスを作成します。標準の{}フォーマッタを使用して製品をプリントし、カスタム表示出力を確認します。
Display トレイトでは、fmt メソッドを手動で実装する必要があります。Rustは Debug のように自動的に派生(derive)させることはできません。これにより、型がユーザーにどのように表示されるかを完全に制御できます。
出力は、製品をクリーンでユーザーフレンドリーな形式で表示する必要があります:
{name} - ${price}例えば、入力が Wireless Mouse と 29.99 の場合:
Wireless Mouse - $29.99製品名と価格(f64 としてパース)の2つの入力を受け取ります。
チートシート
Display トレイトは、ユーザー向けの出力のために設計されており、println! における {} フォーマッタを機能させます。Debug とは異なり、手動で実装する必要があります。
Display を実装するには、fmt モジュールを取り込み、fmt メソッドを実装します。
use std::fmt;
struct Temperature {
celsius: f64,
}
impl fmt::Display for Temperature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}°C", self.celsius)
}
}
fmt メソッドは Formatter を受け取り、fmt::Result を返します。write! マクロを使用して出力をフォーマットし、self を通じて構造体のフィールドにアクセスします。
{} フォーマッタを使用して構造体を出力します。
let temp = Temperature { celsius: 23.5 };
println!("{}", temp); // 23.5°C
主な違い: Debug ({:?}) はデバッグ用にデータ構造を表示しますが、Display ({}) はエンドユーザー向けに整えられた出力を提供します。
自分で試してみよう
mod product;
use product::Product;
fn main() {
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = 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: name と price を使用して Product インスタンスを作成する
// TODO: {} フォーマッタを使用して product を出力する
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。