コンテンツにスキップ

Rustの出力

println! はこれまでに何度も使ってきましたね。このページでは、ほかにもよく出てくる出力用のマクロと、それぞれをどんなときに使えばいいかを紹介します。

println! はテキストを表示して、最後に改行を加えます。print! も同じようにテキストを表示しますが、改行は加えません。

fn main() {
print!("こんにちは、");
print!("世界");
println!("!");
}

実行結果:

こんにちは、世界!
▶ 実際に試してみよう

3回の呼び出しがすべて同じ行に表示されていますね。改行するのは println! だけです。実際にはほとんどいつも println! を使います。print! が役に立つのは、主に1行を少しずつ組み立てて表示したいときです。

プレースホルダー:{} と変数名

Section titled “プレースホルダー:{} と変数名”

{} がプレースホルダーとして使われるのは、すでに見てきました。ここを埋めるには、文字列のあとに値を渡す方法と、波かっこの中に変数名を直接書く方法の2つがあります。

fn main() {
let name = "Ferris";
let age = 10;
println!("{}は{}歳です", name, age); // 位置で指定
println!("{name}は{age}歳です"); // 直接埋め込む(結果は同じ)
}

実行結果:

Ferrisは10歳です
Ferrisは10歳です
▶ 実際に試してみよう

どちらの行も同じ内容を表示します。直接埋め込むスタイル({name})は比較的新しい書き方で、たいていこちらのほうが読みやすいので、使えるときはこちらを使いましょう。

format! — 表示する代わりに文字列を作る

Section titled “format! — 表示する代わりに文字列を作る”

整形したテキストをすぐに表示するのではなく、String として受け取りたいこともあります。たとえば、変数に保存したり、別の関数に渡したりしたいときです。そんなときに使うのが format! です。使い方は println! とまったく同じですが、表示する代わりに String を返します。

fn main() {
let name = "Ferris";
let message = format!("こんにちは、{name}さん!");
println!("{message}");
}

実行結果:

こんにちは、Ferrisさん!
▶ 実際に試してみよう

普通の {} が使えるのは、自分自身をテキストとして表示する方法を知っている値、つまり数値、文字列、真偽値などだけです。タプルや構造体のような複雑な値に {} を使うと、コンパイルが通りません。代わりに {:?}(「デバッグ」用の書式)を使いましょう。

fn main() {
let point = (3, 7);
println!("{:?}", point);
}

実行結果:

(3, 7)
▶ 実際に試してみよう

大きな値を複数行で見やすく表示したいときは、{:#?}(整形表示、pretty-print)を使います。

fn main() {
let point = (3, 7);
println!("{:#?}", point);
}

実行結果:

(
3,
7,
)
▶ 実際に試してみよう

よく使う書式指定のテクニックをいくつか紹介します。

fn main() {
let pi = 3.14159;
println!("{:.2}", pi); // 小数点以下2桁 -> 3.14
println!("{:5}", 42); // 幅5になるよう空白で埋める -> " 42"
println!("{:08.2}", pi); // ゼロで埋める -> 00003.14
}

実行結果:

3.14
42
00003.14
▶ 実際に試してみよう

これらを暗記する必要はありません。数値の桁をそろえたり、小数を丸めたりしたいときのために、こういう方法があると知っておけば十分です。

テキストをそろえる、波かっこを表示する

Section titled “テキストをそろえる、波かっこを表示する”

幅の指定はテキストにも使えます。しかも、値を左右どちらに寄せるかも選べます。: のあとに <(左寄せ)、>(右寄せ)、^(中央寄せ)のどれかを書き、続けて幅を書きます。その前に、- のような埋め草の文字を置くこともできます。

この例の文字列は英語のままにしています。日本語の文字は画面上で半角2文字分の幅を取るのに、Rustは1文字として数えるので、列がずれてしまうからです。

fn main() {
let coffee = 3.5;
let bagel = 2.25;
println!("{:-^20}", " MENU ");
println!("{:<12}{:>8}", "Item", "Price");
println!("{:<12}{:>8.2}", "Coffee", coffee);
println!("{:<12}{:>8.2}", "Bagel", bagel);
println!("{:<12}{:>8.2}", "Total", coffee + bagel);
}

実行結果:

------- MENU -------
Item Price
Coffee 3.50
Bagel 2.25
Total 5.75
▶ 実際に試してみよう

{:>8.2} を分解して読んでみましょう。> は右寄せ、8 は幅、.2 は小数点以下2桁という意味です。数値を右寄せにすると小数点の位置がそろうので、レシートや表ではよくこうします。

では、出力に本物の { を表示したいときはどうすればいいでしょうか。波かっこは「プレースホルダー」を意味するので、2つ重ねて書きます。{{ で { が、}} で } が表示されます。

fn main() {
println!("集合: {{{}, {}}}", 1, 2);
}

実行結果:

集合: {1, 2}
▶ 実際に試してみよう

商品名 "ノート" と価格 2.5 を保存して、ノートは2.50ドルです と表示してください。ヒント:{:.2} は小数点以下2桁に丸めます。直接埋め込む書き方でも使えて、{price:.2} のように書けます。

解答を見る
fn main() {
let item = "ノート";
let price = 2.5;
println!("{item}は{price:.2}ドルです");
}

実行結果:

ノートは2.50ドルです
▶ 実際に試してみよう

2. ラベルを作って、2通りで表示しよう

Section titled “2. ラベルを作って、2通りで表示しよう”

format! を使って、名前 "ferris" と数値 7 から ferris-7 というラベルを作ってください。それを {} と {:?} で1回ずつ表示して、違いを見つけましょう。ヒント:format! には println! とまったく同じプレースホルダーが使えます。

解答を見る
fn main() {
let name = "ferris";
let id = 7;
let label = format!("{name}-{id}");
println!("{label}");
println!("{label:?}");
}

実行結果:

ferris-7
"ferris-7"
▶ 実際に試してみよう

デバッグ出力では、テキストが引用符付きで表示されるので、どこから始まってどこで終わるのかがはっきりわかります。値に余計な空白が入っているときに便利です。

  • println! は最後に改行して表示し、print! は改行しません。
  • {} と {name} は、自分自身を表示できる(Display を実装した)値のためのプレースホルダーです。
  • format! は println! と同じように使えますが、表示する代わりに String を返します。
  • {:?}(と {:#?})は、{} では表示できない値も含めて、デバッグ用に値を表示します。
  • {:.2} で小数を丸め、<、>、^ と幅でテキストをそろえます。{{ と }} で波かっこそのものを表示します。

理解度チェック

1. println! と print! の違いは何ですか?

2. タプルを表示するとき、{} ではなく {:?} を使うのはなぜですか?

スコア: 0 / 2