可変参照のライフタイムにおける所有権の移動と再借用
元ネタ
いずれのケースでもm2の型は&mut i32に相当するが、厳密には参照のライフタイム(lifetime)が異なる別の型である
可変参照の変数束縛
ライフタイムが同一かどうかで、所有権が移動するかどうかが決まる。
- 同一: 移動する
- 異なる: 移動しない (再借用)
ライフタイムが同一
型を明示しなければ、同一ライフタイムが割り当てられ、可変参照の所有権が移動する
let mut src = String::from("Hello"); let m1 = &mut src; { let m2 = m1; m2.push_str(" World"); } dbg!(m1); error[E0382]: use of moved value: `m1` | 3 | let m1 = &mut src; | -- move occurs because `m1` has type `&mut String`, which does not implement the `Copy` trait 4 | { 5 | let m2 = m1; | -- value moved here ... 8 | dbg!(m1); | ^^ value used here after move
ライフタイムが異なる
型を明示すると、そのスコープのライフタイムが割り当てられ、所有権は移動しない。(再借用される)
fn main() { let mut src = String::from("Hello"); let m1 = &mut src; // m1の型は &'a mut String { let m2: &mut String = m1; // m2の型は &'b mut String m2.push_str(" World"); } dbg!(m1); // Hello Wordl
所有権
- 変数が値の所有権を持つ。(値は複数の変数の所有権を持つことができる → Rc)
- 参照型への束縛は、所有権を失わない (参照は値を借用する)
- 可変参照型から可変参照型への束縛は、ライフタイムによる
- ライフタイムが同一: 所有権を失う
- ライフタイムが異なる: 再借用