画面に文字を表示する

#println!

こんな感じで画面に文字を表示できます。

~~~rust
fn main(){
    println!("画面に出力する文字列");
}
~~~
画面表示に関わっているのは以下のコードです。
`println!`は文字列をコンソール(黒い文字だけの画面)に出力して、その後改行します。

~~~rust
println!("画面に出力する文字列");
~~~

Rustでは文字列はダブルクォーテーション`"`で囲います。ダブルクォーテーションで囲めばそれは文字列として認識され、内容はRustの構文として認識されません。

##プレースホルダ
数値などを表示したい場合はプレースホルダを使います。

~~~rust
fn main(){
    //{}がプレースホルダ。文字列の後にカンマで区切って数値などのデータを書く。
    println!("3 * 4 + 2 = {}",3 * 4 + 2);
}
//実行結果：3 * 4 + 2 = 14
~~~
カンマ `,` の後に書いた数値がプレースホルダの位置に挿入されています。

##書式の指定
`format!`マクロや`print!` `println!`等のマクロはプレースホルダの中（`{`と`}`の間）に書式を書くと、書式を指定することが出来ます。
`plintln!`マクロのフォーマット機能は[std::fmtのrustdoc](https://doc.rust-lang.org/std/fmt/index.html)で詳細を確認できます。
フォーマット文字列は以下の構文で記述します。

~~~
format_string := <text> [ maybe-format <text> ] *
maybe-format := '{' '{' | '}' '}' | <format>
format := '{' [ argument ] [ ':' format_spec ] '}'
argument := integer | identifier

format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type]
fill := character
align := '<' | '^' | '>'
sign := '+' | '-'
width := count
precision := count | '*'
type := identifier | '?' | ''
count := parameter | integer
parameter := argument '$'
~~~
これはたぶんBNFでしょう。
`:=`の右側の通りに記号を並べると左辺の記号として認識されます。
`|`は記号の並びに複数のパターンがあることを表します。`|`を区切りとしてどれか一つが左辺の記号として認識されます。
書式を指定しているのは`format_spec`(空行の次にある最も長い行)です。
`format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type]`
たくさんのオプションが用意されています。順にみていきます。

##[[fill]align] - アライメントと空白を埋める文字の指定
右寄せ・中央・左寄せの指定と、空白を埋める文字を指定します。
位置を指定する場合は文字列の最小幅である`[width]`の指定もセットになると思います。
以下は5桁、空白を`-`で埋めるの書式です。5桁以上の場合はすべての桁が表示されます。
後述しますが、数値の場合の0埋めは`[fill]`で行うと符号やプレフィックスまで移動するので`` [`0`] ``のほうが適しています。

~~~rust
fn main(){
    println!("「{:->5}」", 3); // 「----3」
    println!("「{:-^5}」", 3); // 「--3--」
    println!("「{:-<5}」", 3); // 「3----」
    println!("「{:->5}」", 1234567); // 「1234567」
    println!("「{:-^5}」", 1234567); // 「1234567」
    println!("「{:-<5}」", 1234567); // 「1234567」
}
~~~

##[sign] - 符号`+`を省略せずに表示する
符号を表示できます。
しかし、`-`は現在(2020/3/7)使われていないようです。
数値がマイナスの値であれば`-`がつくのであまり問題にはならないでしょう。
`[sign]`と`[width]`を組み合わせる場合は符号の位置に気を付けてください。

~~~rust
fn main(){
    println!("「{:+}」", 123); // 「+123」 「+」の表示を強制する
    println!("「{:+}」", -123); // 「-123」　マイナスの時はちゃんと「-」がつきます
    println!("「{:0>+7}」",123); // 「000+123」　テキスト処理的なゼロ埋め
    println!("「{:+07}」", 123); // 「+000123」　数学的？なゼロ埋めはwidthの前に0を書く
}
~~~

##[#] - プレフィックス・改行・インデントを整える
`[type]`と併用して使います。プレフィックスを付けたり、改行やインデントを入れたりする機能です。
``[`#`]``に対応していない`[type]`もあります。
Rustdocに一覧が記載されています。

~~~
#? - プリティプリント(改行やインデントなどで形を整えた状態)のデバッグフォーマット
#x - 0xで始まる16進数表示　小文字
#X - 0xで始まる16進数表示　大文字
#b - 0bで始まる2進数表示
#o - 0oで始まる8進数表示
~~~
これらの他にも以下の記載が使用できました。2進数、8進数はダメでした。

~~~
#x? - プリティプリントのデバッグフォーマットで数値が16進数表示　小文字
#X? - プリティプリントのデバッグフォーマットで数値が16進数表示　大文字
~~~

###\#?
デバッグフォーマットといいます。
データの構造と値を文字列に変換することが出来ます。


~~~rust
#[derive(Debug)]    // これを直前に書くとデバッグフォーマットが使えるようになる
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let origin = Point { x: 123, y: 456 };
    println!("The origin is: {:?}", origin);    // ただのデバッグフォーマット
    println!("The origin is: {:x?}", origin);   // デバッグフォーマットで、数値が16進数表示(小文字)
    println!("The origin is: {:#?}", origin);   // 改行とインデント付きの(プリティプリントの)デバッグフォーマット
    println!("The origin is: {:#X?}", origin);  // プリティプリントのデバッグフォーマットで、数値が16進数表示(大文字)
}
~~~
実行結果

~~~
The origin is: Point { x: 123, y: 456 }
The origin is: Point { x: 7b, y: 1c8 }
The origin is: Point {
    x: 123,
    y: 456,
}
The origin is: Point {
    x: 0x7B,
    y: 0x1C8,
}
~~~

###\#x,\#X,\#b,\#o
〇〇進数表示でプレフィックスがつきます。

~~~rust
fn main() {
    println!("「{:#x}」", 123); // 「0x7b」
    println!("「{:#X}」", 123); // 「0x7B」
    println!("「{:#b}」", 123); // 「0b1111011」
    println!("「{:#o}」", 123); // 「0o173」
}
~~~

##['0'][width] - 最小幅の指定と0埋め
`[width]`は変換後の文字列の最小幅を指定するものです。 
`` [`0`] ``は`[width]`の幅に満たない場合にゼロ埋めすることを指定するフラグです。
`[[fill]align]`の`[fill]`でも`[width]`の幅に満たない部分の文字を指定できますが、符号やプレフィックスの位置が異なります。数値として表示する場合は`[fill]`ではなく`` [`0`] ``が適しています。

~~~rust
fn main(){
    println!("「{:10}」", 123);     // 「       123」 widthに10文字を指定
    println!("「{:010}」", 123);    // 「0000000123」 widthに10文字を指定　ゼロ埋め

    // fillで0を指定した場合と`0`の違い　符号やプレフィックスの位置に注目
    println!("「{:+010}」", -123.456);  // 「-00123.456」ゼロ埋め
    println!("「{:0>+10}」", -123.456); // 「00-123.456」>の前に0があるためfillと判定される
    println!("「{:#010b}」", 5);      // 「0b00000101」 ゼロ埋め
    println!("「{:0>#10b}」", 5);     // 「000000b101」 これは2進数だが、16進数と区別ができない
}
~~~

##['.' precision] - 小数点以下の桁数を指定する
これは浮動小数点数の小数点以下の桁数を指定します。

~~~rust
fn main(){
    println!("「{:.3}」", 123.456789);  // 「123.457」 小数点以下4桁以降が丸められた
    println!("「{:.3}」", 100.0004);    // 「100.000」 四捨
    println!("「{:.3}」", 100.0005);    // 「100.001」 五入
}
~~~

##[type] - フォーマットの種類を指定する(16進数や指数表示など)
フォーマットの種類を指定します。何も書かなければ`display`になります。
Rustdocに`[type]`とそれに対応するトレイトの一覧が乗っています。
各トレイトに`fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result`関数が定義されており、これを実装するとユーザー定義型のデータをフォーマットできるようになります。
`Debug`は`#[derive(Debug)] `を書くだけで実装されます。

~~~
nothing ⇒ Display
? ⇒ Debug
x? ⇒ Debug with lower-case hexadecimal integers
X? ⇒ Debug with upper-case hexadecimal integers
o ⇒ Octal
x ⇒ LowerHex
X ⇒ UpperHex
p ⇒ Pointer
b ⇒ Binary
e ⇒ LowerExp
E ⇒ UpperExp
~~~
~~~rust
fn main() {
    println!("「{}」", "Display");  // 「Display」 Displayではデータの中身だけを表示
    println!("「{:?}」", "Debug");  // 「"Debug"」 Debugではリテラルと同じ表示になる
    println!("「{:x?}」", 123);     // 「7b」
    println!("「{:X?}」", 123);     // 「7B」
    println!("「{:o}」", 123);      // 「173」
    println!("「{:x}」", 123);      // 「7b」
    println!("「{:X}」", 123);      // 「7B」
    println!("「{:p}」", &123);     // 「0x7ff6d7312348」 ポインタ　要するにアドレス
    println!("「{:b}」", 123);      // 「1111011」
    println!("「{:e}」", 123.456);  // 「1.23456e2」
    println!("「{:E}」", 123.456);  // 「1.23456E2」
}
~~~



[目次](https://qiita.com/tonesuke/items/52e469f18e747c794376)