LoginSignup
131
76

More than 5 years have passed since last update.

[Rust] 文字列のフォーマット指定(println! / format!)

Posted at

TL;DR

Rustのprintln!のフォーマット指定についての記事です。

長い記事でもありませんが、以下のソースを見れば大体わかります。
https://gist.github.com/YusukeHosonuma/6ee32ade9ac88cbc9fbd6b494154c5a0

はじめに

最近「Rustはいいぞ!」という声を聞いたり、Swiftが影響を受けた言語がRustだったりと、気になったので勉強し始めました。

Rustで標準出力はprintln!マクロで行うのですが、フォーマット指定がC言語などのprintfとは異なります。

以下のあたりのドキュメントに詳しく書かれているのですが、自分でコードを書いていて迷ったりすることもあったのでまとめてみました。(網羅はしていません)

基本

  • println!で標準出力
  • {}がプレースホルダ
  • format!でフォーマット後の文字列を取得(指定方法は同じ)
  • どちらもマクロで実装されている
    • なので実行時のオーバーヘッドが(C言語のprintfよりは)少ない(はず)
    • ただコンパイルエラーメッセージがわかりづらいことがある
println!("Hello world!");
println!("Hello {}!", "world");

let s = format!("Hello, {} !!", "Rust"); // s = "Hello, Rust !!"

プレースホルダ

  • {} が基本で引数が順に埋められる
  • {n} で n番目(0始まり)の引数で置き換える
  • {name}name="value" と指定した引数で置き換えられる
println!("{} | {} | {1} | {three} | {four}",
         "One",
         "Two",
         three="three",
         four=4);
// => One | Two | Two | three | 4

揃え(Align)

  • : の後に条件を指定
  • <n が n桁で左寄せ
  • >n が n桁で右寄せ
  • ^n が n桁で中央寄せ
  • >0n または <0n で「0埋め」
println!("{0: <8} | {1: >8} | {2: ^8} | {3: <08} | {4: >08} | {hundred: >08}",
         "Left",
         "Right",
         "Center",
         42,
         999,
         hundred=100);
// => Left     |    Right |  Center  | 42000000 | 00000999 | 00000100

基数 / 小数点

  • bがバイナリ表現
  • oが8進数
  • xが16進数(Xで大文字出力)
  • eが指数表現(Eで大文字出力)
println!("{:b}", 1234);  // => 10011010010
println!("{:o}", 1234);  // => 2322
println!("{:x}", 1234);  // => 4d2
println!("{:X}", 1234);  // => 4D2
println!("{:e}", 12.34); // => 1.234e1
println!("{:E}", 12.34); // => 1.234E1

fmt::Display / fmt::Debug

  • {} では fmt::Display の実装が使われ
  • {:?} では fmt::Debug の実装が使われる
// 構造体の宣言
struct Point {
    x: i32,
    y: i32,
}

// fmt::Display トレイトの実装
impl fmt::Display for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
       write!(f, "({}, {})", self.x, self.y)
    }
}

// fmt::Debug トレイトの実装
impl fmt::Debug for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Point(x: {}, y: {})", self.x, self.y)
    }
}

let p = Point { x: 1, y: 2 };
println!("{}", p);    // => (1, 2)
println!("{:?} ", p); // => Point(x: 1, y: 2)

終わり

Rustはいいぞ!

131
76
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
131
76