第5回です。
前回はこちら。
[第5回の様子]
2021/08/11に第5回を開催した。
内容としてはRust By Example 日本語版の「1.2.2.1. テストケース: リスト」、「1.2.3. フォーマット」、「2. 基本データ型」を読んで演習に取り組んだ。
参加者はたぶん全部で8人。やはり連続して10人以上の人数の参加は難しそうだ。
今回も、前回終了時に決めておいたメンバーにドライバーをお願いした。今のところドライバー指名制度はうまくいっている。
今週も開催前後のSlackでのやりとりがたくさん🎉
復習にはげむ若者。
おいでよRust dojo!
ドライバーからもナビゲータからも参加報告!
そんな日もあるよね...参加人数が増えるとこの辺の調整がしづらくなるのがネック。6月までやってたKotlin dojoは人数が少なかったので気軽に別の曜日に移したりしていた。
[学んだこと]
- 1.2.2.1. テストケース: リスト
- write!マクロを複数回よびだす場合、毎回生成される
fmt::Result
を適切に処理する必要がある:ここで?
演算子を利用すると、エラーが発生した場合のみエラーを返してくれるようになる
write!(f, "{}", value)?;
- やや冗長な書き方として、以下のように表現することもできるがあまり使われないらしい
try!(write!(f, "{}", value));
struct List(Vec<i32>);
という構造体を[1, 2, 3]
のように出力するには、以下のような実装になる
use std::fmt; struct List(Vec<i32>); impl fmt::Display for List { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let vec = &self.0; write!(f, "[")?; for (count, v) in vec.iter().enumerate() { if count != 0 { write!(f, ", ")?; } write!(f, "{}", v)?; } write!(f, "]") } } fn main() { let v = List(vec![1, 2, 3]); println!("{}", v); }
- この出力を
[0: 1, 1: 2, 2: 3]
に修正する演習問題が出ていた - 出力形式の修正だけなので、以下のように簡単にできた。やったー!
(前後は省略) for (count, v) in vec.iter().enumerate() { if count != 0 { write!(f, ", ")?; } write!(f, "{}: {}", count, v)?; // インデックスの出力を追加する }
- 1.2.3. フォーマット
- これまで、
{:b}
のようなフォーマット文字列がいくつか登場した - フォーマット文字列の一覧は以下のページにまとまっている(全部で10個)
{:X}
は大文字の16進数、{:o}
は8進数など、それぞれのトレイトが実装されている。- 演習問題は以下のColor構造体を
RGB (0, 3, 254) 0x0003FE
のように出力せよというもの
struct Color { red: u8, green: u8, blue: u8, }
- ヒントが用意されていて、
{:02}
で幅を2に指定し、空白を0で埋められるようだ - ヒントと、最初の
{:X}
で大文字16進数が出力できる、を参考に、最初は以下のように実装した
impl Display for Color { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!( f, "RGB({red}, {green}, {blue}) 0x{red:X02}{green:X02}{blue:X02}", red = self.red, green = self.green, blue = self.blue ) } }
- しかしこれは以下のようにエラーになってしまった
error: invalid format string: expected `'}'`, found `'0'` --> src/main.rs:43:50 | 43 | "RGB({red}, {green}, {blue}) 0x{red:X02}{green:X02}{blue:X02}", | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{`
- 1分程度の試行錯誤の結果、
{:X02}
ではなく{:02X}
のようにフォーマットを指定することで演習問題をクリアできた。やったー! - 2. 基本データ型
- Rustのプリミティブは符号付き整数(i8, i16など)、符号なし整数(u8, u16など)、浮動小数(f32, f64)、char、bool、unit型
()
がある isize
、usize
は実行環境が32ビットか64ビットかで変わるポインタのサイズらしい- charは4バイトでユニコードが扱えるらしい。Javaとはちょっと違う、Goのruneっぽいかも。
- unit型はよくわからなかったけどvoidみたいなものらしい。そういえばKotlinでもUnit型が出てきたな。
- 複合型として、配列(
[1, 2, 3]
とか)とタプル((1, true)
とか)がある - 変数を宣言するときは
let
を使う
let a_float: f64 = 1.0; // 普通の型指定 let an_integer = 5i32; // サフィックス型指定
- サフィックスがない場合、小数は
f64
、整数はi32
が使われる - 型指定しなくても推論してくれる
let mut inferred_type = 12; // i64
- 上記のように
mut
をつけると再代入できるようだ。Kotlinでいうvar
か。 - ただし、ミュータブルな型でも異なる型の代入は
error[E0308]: mismatched types
とコンパイルエラーになってしまう - ミュータブルであろうとなかろうと、同名の変数を別の型で宣言することはできる(シャドウイング)
let mut mutable = 12; mutable = 21; let mutable = true;
[まとめ]
モブプログラミングスタイルでRust dojoを開催した。
今回もたくさん「やったー!」ができた。やったー!
今週のプルリクエストはこちら。