第21回です。
前回はこちら。
[第21回の様子]
2021/12/08に第21回を開催した。
内容としてはRust By Example 日本語版の「8.5. match」、「8.5.1. デストラクト」、「8.5.1.1. タプル」、「8.5.1.2. 列挙型」、「8.5.1.3. ポインタとref」、「8.5.1.4. 構造体」に取り組んだ。
参加者は、ちょっと減って、6人だったけれど、どこから嗅ぎつけたのか新メンバーが参加してくれた。ありがたい🙏
Slackでの書き込みもいつもより活発だった。




次回お待ちしてます〜。


[学んだこと]
- 8.5. match
- JavaやCでいう
switchに該当するのがRustのmatch - 条件判定で
|や..=を使えるのは柔軟でよさそう
let number = 13;
match number {
// 単一の値とのマッチをチェック
1 => println!("One!"),
// いくつかの値とのマッチをチェック
2 | 3 | 5 | 7 | 11 => println!("This is a prime"),
// 特定の範囲の値とのマッチをチェック
13..=19 => println!("A teen"),
// その他の場合の処理
_ => println!("Ain't special"),
}
matchは式として代入もできる
let boolean = true;
// マッチは式でもある。
let binary = match boolean {
// マッチは全ての可能な値をカバーしなくてはならない
false => 0,
true => 1,
}; // 最後のセミコロンが必要になる
- matchはとりうる値の範囲を全てカバーしないとコンパイルエラーになる
let boolean = true;
let binary = match boolean {
false => 0,
};
// 以下のコンパイルエラー
error[E0004]: non-exhaustive patterns: `true` not covered
--> src/main.rs:24:24
|
24 | let binary = match boolean {
| ^^^^^^^ pattern `true` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
= note: the matched value is of type `bool`
- 8.5.1. デストラクト
- matchでは値をデストラクトして取り出すことができる
- 8.5.1.1. タプル
- タプルから値を取り出す場合
let pair = (0, -2);
match pair {
(0, y) => println!("First is `0` and `y` is `{:?}`", y), // こちらにマッチする
(x, 0) => println!("`x` is `{:?}` and last is `0`", x),
_ => println!("It doesn't matter what they are"),
}
- 8.5.1.2. 列挙型
- 列挙型でも同様
enum Color { Red, Blue, Green, RGB(u32, u32, u32), } fn main() { let color = Color::RGB(122, 17, 40); match color { Color::Red => println!("The color is Red!"), Color::Blue => println!("The color is Blue!"), Color::Green => println!("The color is Green!"), Color::RGB(r, g, b) => println!("Red: {}, green: {}, and blue: {}!", r, g, b), } }
- 8.5.1.3. ポインタとref
- ポインタをデリファレンスする場合には
*を用いる - デストラクトには
&、ref、ref mut を利用する
fn main() {
// `i32`型へのリファレンスをアサインする。
// `&`によってリファレンスであることを明示している。
let reference = &4;
match reference {
// 上で定義した`reference`という変数が`&val`とのパターンマッチ
// に用いられた場合、以下の2つの値が比較されていることになる。
// `&i32`
// `&val`
// ^ よって`&`を落とせば、`i32`が`val`にアサインされることがわかる。
&val => println!("Got a value via destructuring: {:?}", val),
// ここでは値がコピーされており、println!("{:p}", &val);でポインタを見るとreferenceとは別のものになっている
}
// To avoid the `&`, you dereference before matching.
// `&`を使用したくない場合は、マッチングの前にデリファレンスする。
match *reference {
val => println!("Got a value via dereferencing: {:?}", val),
// ここでもポインタは変わっている
}
}
- &とrefは大体同じ、ということらしい
// 上記の以下の部分を let reference = &4; // このように書き換えても動く let ref reference = 4;
- 値を変更する場合
let mut mut_value = 6; // `ref mut`を使用。 match mut_value { ref mut m => { // リファレンスを取得、値を変更するためにはデリファレンスする必要がある。 *m += 10; println!("We added 10. `mut_value`: {:?}", m); // 16 }, } println!("{:?}", mut_value); // 参照先の値が変更されているので16が出力される
- 8.5.1.4. 構造体
- 構造体の場合はフィールド名を指定してデストラクトする
fn main() {
struct Foo {
x: (u32, u32),
y: u32,
}
let foo = Foo { x: (1, 2), y: 3 };
match foo {
Foo { x: (1, b), y } => println!("First of x is 1, b = {}, y = {} ", b, y),
// 構造体をデストラクトして変数をリネーム
// 順番は重要ではない。
Foo { y: 2, x: i } => println!("y is 2, i = {:?}", i),
// 一部の変数を無視することもできる。
Foo { y, .. } => println!("y = {}, we don't care about x", y),
// `x`に言及していないため、以下はエラーになる。
//Foo { y } => println!("y = {}", y),
}
}
[まとめ]
モブプログラミングスタイルでRust dojoを開催した。
match式完全に理解した。でも参照は難しい...。
今週のプルリクエストはこちら。