Rust dojo第5回を開催した

第5回です。

前回はこちら。

kdnakt.hatenablog.com

 

 

[第5回の様子]

2021/08/11に第5回を開催した。

 

内容としてはRust By Example 日本語版の「1.2.2.1. テストケース: リスト」、「1.2.3. フォーマット」、「2. 基本データ型」を読んで演習に取り組んだ。

 

参加者はたぶん全部で8人。やはり連続して10人以上の人数の参加は難しそうだ。

 

今回も、前回終了時に決めておいたメンバーにドライバーをお願いした。今のところドライバー指名制度はうまくいっている。

  

今週も開催前後のSlackでのやりとりがたくさん🎉

復習にはげむ若者。 

f:id:kidani_a:20210813010247p:plain

 

おいでよRust dojo

f:id:kidani_a:20210813010346p:plain

f:id:kidani_a:20210813010424p:plain

f:id:kidani_a:20210813010500p:plain

 

ドライバーからもナビゲータからも参加報告!

f:id:kidani_a:20210813010628p:plain

f:id:kidani_a:20210813010933p:plain

f:id:kidani_a:20210813011106p:plain

 

そんな日もあるよね...参加人数が増えるとこの辺の調整がしづらくなるのがネック。6月までやってたKotlin dojoは人数が少なかったので気軽に別の曜日に移したりしていた。

f:id:kidani_a:20210813010715p:plain

 

 

[学んだこと]

  • 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個)

doc.rust-lang.org

  • {: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型()がある
  • isizeusizeは実行環境が32ビットか64ビットかで変わるポインタのサイズらしい
  • charは4バイトでユニコードが扱えるらしい。Javaとはちょっと違う、Goのruneっぽいかも。
  • unit型はよくわからなかったけどvoidみたいなものらしい。そういえばKotlinでもUnit型が出てきたな。

doc.rust-lang.org

  • 複合型として、配列([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を開催した。

今回もたくさん「やったー!」ができた。やったー!

 

今週のプルリクエストはこちら。

github.com