error[E0382]: use of moved value: `var`

error[E0382]: borrow of moved value: `var`

error[E0382]: use of partially moved value: `var`

error[E0382]: borrow of partially moved value: `var`

ムーブ済の変数にアクセスしようとした。

パターン

パターン A1

基本形 (変数の使用)

ムーブ後に変数を使おうとしたパターン。

サンプル

以下では、func(var) による var のムーブ後に var を使用している。


fn main() {
    let var = MyType(42);
    func(var);
    var.show_value();
}

fn func(var: MyType) {
    _ = var;
}

struct MyType(i32);
impl MyType {
    fn show_value(self) {
        println!("val: {}", self.0)
    }
}

error[E0382]: use of moved value: `var`
  --> src\main.rs:4:5
   |
2  |     let var = MyType(42);
   |         --- move occurs because `var` has type `MyType`, which does not implement the `Copy` trait
3  |     func(var);
   |          --- value moved here
4  |     var.show_value();
   |     ^^^ value used here after move
   |
note: consider changing this parameter type in function `func` to borrow instead if owning the value isn't necessary
  --> src\main.rs:7:14
   |
7  | fn func(var: MyType) {
   |    ----      ^^^^^^ this parameter takes ownership of the value
   |    |
   |    in this function
note: if `MyType` implemented `Clone`, you could clone the value
  --> src\main.rs:11:1
   |
3  |     func(var);
   |          --- you could clone this value
...
11 | struct MyType(i32);
   | ^^^^^^^^^^^^^ consider implementing `Clone` for this type

パターン A2

基本形 (変数の参照)

ムーブ後に変数を参照しようとしたパターン。

サンプル

以下では、func(var) による var のムーブ後に var を参照している。


fn main() {
    let var = MyType(42);
    func(var);
    var.show_value();
}

fn func(var: MyType) {
    _ = var;
}

struct MyType(i32);
impl MyType {
    fn show_value(&self) {
        println!("val: {}", self.0)
    }
}

error[E0382]: borrow of moved value: `var`
  --> src\main.rs:4:5
   |
2  |     let var = MyType(42);
   |         --- move occurs because `var` has type `MyType`, which does not implement the `Copy` trait
3  |     func(var);
   |          --- value moved here
4  |     var.show_value();
   |     ^^^ value borrowed here after move
   |
note: consider changing this parameter type in function `func` to borrow instead if owning the value isn't necessary
  --> src\main.rs:7:14
   |
7  | fn func(var: MyType) {
   |    ----      ^^^^^^ this parameter takes ownership of the value
   |    |
   |    in this function
note: if `MyType` implemented `Clone`, you could clone the value
  --> src\main.rs:11:1
   |
3  |     func(var);
   |          --- you could clone this value
...
11 | struct MyType(i32);
   | ^^^^^^^^^^^^^ consider implementing `Clone` for this type

パターン B1

部分的ムーブ (変数の使用)

部分的ムーブ後に変数を使おうとしたパターン。

サンプル


fn main() {
    let var = MyType(Sub(42));
    func(var.0);
    var.show_sub();
}

fn func(sub: Sub) {
    _ = sub;
}

struct MyType(Sub);
impl MyType {
    fn show_sub(self) {
        println!("sub: {}", self.0.0);
    }
}

struct Sub(i32);

error[E0382]: use of partially moved value: `var`
 --> src\main.rs:4:5
  |
3 |     func(var.0);
  |          ----- value partially moved here
4 |     var.show_sub();
  |     ^^^ value used here after partial move
  |
  = note: partial move occurs because `var.0` has type `Sub`, which does not implement the `Copy` trait

パターン B2

部分的ムーブ (変数の参照)

部分的ムーブ後に変数を参照しようとしたパターン。

サンプル

以下では、func(var.0) による var の部分的ムーブ後に var を参照している。


fn main() {
    let var = MyType(Sub(42));
    func(var.0);
    var.show_sub();
}

fn func(sub: Sub) {
    _ = sub;
}

struct MyType(Sub);
impl MyType {
    fn show_sub(&self) {
        println!("sub: {}", self.0.0);
    }
}

struct Sub(i32);

error[E0382]: borrow of partially moved value: `var`
 --> src\main.rs:4:5
  |
3 |     func(var.0);
  |          ----- value partially moved here
4 |     var.show_sub();
  |     ^^^ value borrowed here after partial move
  |
  = note: partial move occurs because `var.0` has type `Sub`, which does not implement the `Copy` trait

パターン C

ループ内のムーブ

前回ループのムーブにより値が失われているパターン。

サンプル

以下では var.show_value()var が失われるためループできない。


fn main() {
    let var = MyType(42);
    for _ in 0..3 {
        var.show_value();
    }
}

struct MyType(i32);
impl MyType {
    fn show_value(self) {
        println!("val: {}", self.0)
    }
}

error[E0382]: use of moved value: `var`
  --> src\main.rs:4:9
   |
2  |     let var = MyType(42);
   |         --- move occurs because `var` has type `MyType`, which does not implement the `Copy` trait
3  |     for _ in 0..3 {
   |     ------------- inside of this loop
4  |         var.show_value();
   |         ^^^ ------------ `var` moved due to this method call, in previous iteration of loop
   |
note: `MyType::show_value` takes ownership of the receiver `self`, which moves `var`
  --> src\main.rs:10:19
   |
10 |     fn show_value(self) {
   |                   ^^^^

解決策

ムーブで失われた変数を再設定するとよい。


fn main() {
    let mut var = MyType(42);
    for _ in 0..3 {
        var.show_value();
        var = MyType(42);
    }
}

struct MyType(i32);
impl MyType {
    fn show_value(self) {
        println!("val: {}", self.0)
    }
}

解決策 (共通)

全てのパターンで以下の解決策が使える。

(解決策の各例はパターン A1 を基にしている)。

解決策 1

参照による引数渡し

引数の型を参照型に変更する。


fn main() {
    let var = MyType(42);
    func(&var);
    var.show_value();
}

fn func(var: &MyType) {
    _ = var;
}

struct MyType(i32);
impl MyType {
    fn show_value(self) {
        println!("val: {}", self.0)
    }
}

解決策 2

クローンによる引数渡し

引数の型に Clone を実装し、引数にクローンした値を使う。


fn main() {
    let var = MyType(42);
    func(var.clone());
    var.show_value();
}

fn func(var: MyType) {
    _ = var;
}

#[derive(Clone)]
struct MyType(i32);
impl MyType {
    fn show_value(self) {
        println!("val: {}", self.0)
    }
}

解決策 3

コピーによる引数渡し

引数の型に Copy を実装し、引数に自動コピーされた値を使う。


fn main() {
    let var = MyType(42);
    func(var);
    var.show_value();
}

fn func(var: MyType) {
    _ = var;
}

#[derive(Clone, Copy)]
struct MyType(i32);
impl MyType {
    fn show_value(self) {
        println!("val: {}", self.0)
    }
}