先週に続いて第2回です。
[第2回の様子]
2021/07/21に第2回を開催した。
内容としてはRust By Example 日本語版の「1.2. フォーマットしてプリント」を読んで演習を解いて、std::fmtモジュールのドキュメントの数字のフォーマットの部分を試した。
参加者はおそらく全部で16人ほど。途中参加の方もいたので最終的に何人いたのかあまり自信がない……。噂を聞きつけたのか、今回から参加してくれたメンバーもいて嬉しかった。
今回はドライバーを参加者にゆずり、ナビゲータ役をやった。あまりモブラーニングのスタイルが伝わっていないのか、人数が多すぎるのか、ナビゲータの方々が静かだったので、自分とドライバーだけが主にしゃべっていた気がする。
ときどきRustに詳しいメンバーからチャットでコメントをもらったり、口頭で補足説明をもらえたりしたので、とても助かった。
開催前後のSlackでのやりとりが今回も活発だった。🎉
各種参加報告とか。
整数型の話とかも。
rustチャンネルにも人が増えてきた。
教材が一部未翻訳だったのでこれはコントリビューションチャンスか?!と思ったら既にプルリクが出ていた。他のやつを見つけたらやろう。
[学んだこと]
- printlnマクロは引数の埋め込まれる位置を指定できる
println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); // Alice, this is Bob. Bob, this is Alice
- 名前付き引数を利用することもできる
println!("{subject} {verb} {object}", object="the lazy dog", subject="the quick brown fox", verb="jumps over"); // the quick brown fox jumps over the lazy dog
:
につづけてフォーマット型を指定することで特殊な出力ができる
println!("{} of {:b} people know binary, the other half doesn't", 1, 2); // 1 of 10 people know binary, the other half doesn't // bでフォーマットすると二進数で表示される
- 以下のようにすると右寄せで出力できる
println!("{number:>width$}", number=1, width=6); // " 1"
- 以下のようにすると0埋めで出力できる
println!("{number:>0width$}", number=1, width=6); // 000001
- フォーマットする引数が足りない場合はコンパイルエラーがでる
println!("My name is {0}, {1} {0}", "Bond"); // error: invalid reference to positional argument 1 (there is 1 argument) // --> src/main.rs:42:31 // | // 42 | println!("My name is {0}, {1} {0}", "Bond"); // | ^^^ // | // = note: positional arguments are zero-based println!("My name is {0}, {1} {0}", "Bond", "James"); // My name is Bond, James Bond
- 構造体を定義するときは
struct
を使う:以下はi32のデータを保持する構造体
#[allow(dead_code)] struct Structure(i32);
- 構造体の出力にはもう少し工夫が必要でこれだけだとコンパイルエラーになる
println!("This struct `{}` won't print...", Structure(3)); // error[E0277]: `Structure` doesn't implement `std::fmt::Display` // --> src/main.rs:54:49 // | // 54 | println!("This struct `{}` won't print...", Structure(3)); // | ^^^^^^^^^^^^ `Structure` cannot be formatted with the default formatter // | // = help: the trait `std::fmt::Display` is not implemented for `Structure` // = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead // = note: required by `std::fmt::Display::fmt` // = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
- 上記エラーメッセージでもトレイト(trait)の話が出た:Javaでいうinterfaceのようなもので、構造体の振る舞いを定義したりできるらしい
fmt::Debug
というトレイトは{:?}
マーカーで、fmt::Display
は{}
で表示される- 演習問題:「Pi is roughly 3.142」を出力する
- ヒントにある小数部の出力について学ぶために、std::fmtのドキュメントを読んで動かしてみた:フォーマット幅とかもっと細かいことできそうだったけど小数のところだけとりあえず読む
- ポイント1:
{:.N}
で小数第N位まで出力できる - 以下の例では
{1:.5}
で1番目の引数を小数第5位まで出力している
println!("Hello {0} is {1:.5}", "x", 0.01); // Hello x is 0.01000
- ポイント2:
{:.N$}
でNに引数の順番または名前を精度として指定できる - 以下の例では、0番目の引数である5を精度として利用し、結果として先の例と同じ出力になる
println!("Hello {1} is {2:.0$}", 5, "x", 0.01); // Hello x is 0.01000
- 名前つき引数を利用する場合も同様
println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01); // Hello x is 0.01000
- ポイント3:
{:.*}
は2つの引数をとる:最初の引数がusize
という整数型で精度を表し、つぎの引数が実際に出力される値となる - 以下の例では、1番目の引数5と2番目の引数0.01がこのフォーマットの対象となり、それぞれ精度と値となる
println!("Hello {} is {:.*}", "x", 5, 0.01); // Hello x is 0.01000
- やや変則的だが、以下のように一部だけ引数の位置を指定すると、それ以外の引数が順番に使われていくらしい
println!("Hello {} is {3:.*} {}", "x", 5, 0.01, 0.02); // Hello x is 0.02000 0.01
[まとめ]
モブプログラミングスタイルでRust dojoをやった!
文字列のフォーマットだけでも随分複雑だなあ……。
今週のプルリクエストはこちら。