第14回です。
前回はこちら。
[第14回の様子]
2021/10/13に第14回を開催した。
内容としてはRust By Example 日本語版の「4.1. ミュータビリティ」、「4.2. スコープとシャドーイング」、「4.3. 宣言」に取り組んだ。
おやすみの人が多かったからか参加者は少なめで、全部で6人くらい。
Slackでの書き込みも相変わらず少なめ。
来週はお待ちしてます!
[学んだこと]
- 4.1. ミュータビリティ
- letで宣言した変数はデフォルトでは変更不可
fn main() { let _immutable_binding = 1; _immutable_binding += 1; } // 以下のコンパイルエラー 2 | let _immutable_binding = 1; | ------------------ | | | first assignment to `_immutable_binding` | help: consider making this binding mutable: `mut _immutable_binding` ... 3 | _immutable_binding += 1; | ^^^^^^^^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable
- mut構文を利用すると変更できる
fn main() { let mut mutable_binding = 1; println!("Before mutation: {}", mutable_binding); // Before mutation: 1 mutable_binding += 1; println!("After mutation: {}", mutable_binding); // After mutation: 2 }
- 4.2. スコープとシャドーイング
- シャドーイングは相変わらずバグりそうで怖い
- 変数にはスコープ({}で囲まれた範囲)があり、スコープ外では参照できない
fn main() { // 新しいスコープ { let short_lived_binding = 2; println!("inner short: {}", short_lived_binding); } println!("outer short: {}", short_lived_binding); } // 以下のコンパイルエラー error[E0425]: cannot find value `short_lived_binding` in this scope --> src/main.rs:21:33 | 21 | println!("outer short: {}", short_lived_binding); | ^^^^^^^ not found in this scopeす
- スコープが変わったりシャドーイングされるとポインタが変わっている
fn main() { let long_lived_binding = 1; println!("outer long: {}, {:p}", long_lived_binding, &long_lived_binding); // outer long: 1, 0x7ffde1f6177c { // 別スコープ let long_lived_binding = 5_f32; println!("inner long: {}, {:p}", long_lived_binding, &long_lived_binding); // inner long: 5, 0x7ffde1f6183c } // 元のスコープ println!("outer long: {}, {:p}", long_lived_binding, &long_lived_binding); // outer long: 1, 0x7ffde1f6177c // シャドーイングによりポインタが変わっている let long_lived_binding = 'a'; println!("outer long: {}, {:p}", long_lived_binding, &long_lived_binding); // outer long: a, 0x7ffde1f61914 }
- 4.3. 宣言
- 変数宣言と初期化は別タイミングでもよい
fn main() { // 宣言 let a_binding; { let x = 2; // 初期化 a_binding = x * x; } println!("a binding: {}", a_binding); // a binding: 4 }
- あ初期化していない変数を利用しようとするとコンパイルエラー
fn main() { let another_binding; println!("another binding: {}", another_binding); } // 以下のコンパイルエラー error[E0381]: borrow of possibly-uninitialized variable: `another_binding` --> src/main.rs:20:37 | 20 | println!("another binding: {}", another_binding); | ^^^^^^^^^^^^^^^ use of possibly-uninitialized `another_binding`
fn main() { let _a = A; // main関数終了後にスコープを外れる println!("End of main()"); // End of main() // Drop A } struct A; impl Drop for A { fn drop(&mut self) { println!("Drop A"); } }
- ただ変数を宣言しただけで初期化しないとdrop()は呼ばれない
fn main() { let _a: A; // なにも出力されない } struct A; impl Drop for A { fn drop(&mut self) { println!("Drop A"); } }
- 上記以外にも、シャドーイングしたら前のオブジェクトがドロップされる実験とか、いろいろやった。
[まとめ]
モブプログラミングスタイルでRust dojoを開催した。
Rustのスコープ、ちょっとだけ理解できた気がする。
今週のプルリクエストはこちら。