可変参照のライフタイムにおける所有権の移動と再借用

元ネタ

yohhoy.hatenadiary.jp

いずれのケースでも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)
  • 参照型への束縛は、所有権を失わない (参照は値を借用する)
  • 可変参照型から可変参照型への束縛は、ライフタイムによる
    • ライフタイムが同一: 所有権を失う
    • ライフタイムが異なる: 再借用

関連

yossan.hatenablog.com ライフタイムとライフタイム付き可変参照 - あるマのメモ書き

参照型 `&T` `&mut T` - あるマのメモ書き