第23回です。
前回はこちら。
[第23回の様子]
2021/12/22に第23回を開催した。
内容としてはRust By Example 日本語版の「8.5.3. バインディング」の続き、「8.6. if let」、「8.7. while let」まで取り組んだ。
参加者は、ちょっと増えて5人。今回は久しぶりに自分がドライバを担当した。
[学んだこと]
- 8.5.3. バインディング(続き)
- matchさせるときに、デストラクトとバインドを同時に利用できる
fn some_number() -> Option<u32> { Some(42) } fn main() { match some_number() { Some(n @ 42) => println!("The Answer: {}!", n), Some(n) => println!("Not interesting... {}", n), _ => (), } } // The Answer: 42!が出力される
- 前回やったように値のとりうる範囲を指定してバインドすることもできる
match some_number() { Some(n @ 40..=42) => { println!("The Answer: {}!", n) }, _ => (), }
- 8.6. if let
- ただ、matchを使ってデストラクトして処理を行うとインデントが2段になる上に、matchの網羅性を満たすための
_ => ()
が必要になりやや冗長 - そんな時は
if let
を使うと良い
let number = Some(7); if let Some(i) = number { println!("Matched {:?}!", i); } // Matched 7!と出力される
if let
を使うと失敗時の処理もelse
ですむ
let letter: Option<i32> = None; if let Some(i) = letter { println!("Matched {:?}!", i); } else { println!("Didn't match a number. Let's go with a letter!"); } // Didn't match a number〜と出力される
- もちろん
else if
も使える
let emoticon: Option<i32> = None; let i_like_letters = false; if let Some(i) = emoticon { println!("Matched {:?}!", i); } else if i_like_letters { println!("Didn't match a number. Let's go with a letter!"); } else { println!("I don't like letters. Let's go with an emoticon :)!"); } // I don't like letters.〜と出力される
- enumに対しても
if let
を用いることができる
// Our example enum enum Foo { Bar, Baz, Qux(u32) } let a = Foo::Bar; if let Foo::Bar = a { println!("a is foobar"); } // a is foobarが出力される
else if let
を使うこともできる
let b = Foo::Baz; if let Foo::Bar = b { println!("b is foobar"); } else if let Foo::Baz = b { println!("b is foobaz"); } // b is foobazが出力される
if let
でもデストラクトした値を利用できる
let c = Foo::Qux(100); if let Foo::Qux(value) = c { println!("c is {}", value); // c is 100と出力される } // @でバインドもできる if let Foo::Qux(value @ 100) = c { println!("c is one hundred"); }
PartialEq
トレイトを実装していないenumは==
で比較できないが、if let
を用いることで条件式として利用できるif let
を使うと代入もできるが、unwrap_or()
を使う方がシンプルに書ける
let number = Some(7); let foo = if let Some(i) = number { i } else { 0 }; println!("{:?}", foo); // 7 // unwrap_or()を使うとより簡潔に書ける let foo = number.unwrap_or(0); println!("{:?}", foo); // 7
- 8.7. while let
- whileでも同様のことができる
let mut optional = Some(0); // optionalがNoneになったら終了 while let Some(i) = optional { if i > 9 { println!("Greater than 9, quit!"); optional = None; } else { println!("`i` is `{:?}`. Try again.", i); optional = Some(i + 1); } }
[まとめ]
モブプログラミングスタイルでRust dojoを開催した。
デストラクトとバインドをいい感じに使いこなせるようになりたい。
今週のプルリクエストはこちら。