🦀
[Rust] 構造体や列挙型の表示 < Debug / Display >
構造体や列挙型を表示したい
- 構造体や列挙型などの変数を
println!()
で表示しようとするとエラーになる - それぞれ要素を取り出してやれば表示することは可能
表示エラー
struct Foo {
value: u32,
string: &'static str,
}
fn main() {
let x = Foo {
value: 123,
string: "abc",
};
println!("{}", x); // 表示が出来ずエラー
}
Debug
デバッグによる表示 - 型の定義に
#[derive(Debug)]
のアトリビュートを付ければデバッグによる表示が可能 - プレースホルダ
{:?}
もしくはマクロdbg!()
で表示をする
デバッグによる表示
#[derive(Debug)] // デバッグのアトリビュート
struct Foo {
value: u32,
string: &'static str,
}
fn main() {
let x = Foo {
value: 123,
string: "abc",
};
println!("{:?}", x); // デバッグ表示( dbg!(x) でも可)
}
実行結果(ターミナル)
Foo { value: 123, string: "abc" }
std::fmt::Display
Displayトレイトの実装 構造体の場合
- 型の定義に
std::fmt::Display
のトレイトを実装すると、自由に表示を設定することが可能 -
write!()
にどのように表示するかを設定する
Displayトレイトの実装(構造体)
use std::fmt; // フォーマットの標準ライブラリクレート
struct Foo {
value: u32,
string: &'static str,
}
impl fmt::Display for Foo { // Display のトレイトの実装
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "value = {}\nstring = {}", self.value, self.string)
}
}
fn main() {
let x = Foo {
value: 123,
string: "abc",
};
println!("{}", x);
}
実行結果(ターミナル)
value = 123
string = abc
列挙型の場合
- 列挙型は
match
でそれぞれのパターンを設定する必要がある
Displayトレイトの実装(列挙型)
use std::fmt; // フォーマットの標準ライブラリクレート
enum Foo {
X,
Y(u32),
Z { value: u32, string: &'static str },
}
impl fmt::Display for Foo { // Display のトレイトの実装
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::X => write!(f, "X"),
Self::Y(n) => write!(f, "{}", n),
Self::Z { value: n, string: m } => write!(f, "x = {} / y = {}", n, m),
}
}
}
fn main() {
let x = Foo::X;
let y = Foo::Y(123);
let z = Foo::Z {
value: 456,
string: "abc",
};
println!("{}", x);
println!("{}", y);
println!("{}", z);
}
実行結果(ターミナル)
X
123
x = 456 / y = abc
write!()
の応用
-
write!()
には変数の要素と関係ない文字列や記号、絵文字などを設定することも可能
絵文字を表示
use std::fmt; // フォーマットの標準ライブラリクレート
enum Foo {
X,
Y,
Z,
}
impl fmt::Display for Foo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::X => write!(f, "Hello!"), // 文字列
Self::Y => write!(f, "('ω')ノ"), // 記号
Self::Z => write!(f, "\u{1f600}"), // 絵文字
}
}
}
fn main() {
let x = Foo::X;
let y = Foo::Y;
let z = Foo::Z;
println!("{}", x);
println!("{}", y);
println!("{}", z);
}
実行結果(ターミナル)
Hello!
('ω')ノ
😀
Discussion