第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のスコープ、ちょっとだけ理解できた気がする。
今週のプルリクエストはこちら。