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

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

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

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

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

パターン

パターン A1

基本形 (変数の使用)

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

サンプル

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


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

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

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

error[E0382]: use of moved value: `val`
  --> src\main.rs:4:5
   |
2  |     let val = MyType(42);
   |         --- move occurs because `val` has type `MyType`, which does not implement the `Copy` trait
3  |     func(val);
   |          --- value moved here
4  |     val.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(val: 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(val);
   |          --- you could clone this value
...
11 | struct MyType(i32);
   | ^^^^^^^^^^^^^ consider implementing `Clone` for this type

パターン A2

基本形 (変数の参照)

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

サンプル

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


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

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

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

error[E0382]: borrow of moved value: `val`
  --> src\main.rs:4:5
   |
2  |     let val = MyType(42);
   |         --- move occurs because `val` has type `MyType`, which does not implement the `Copy` trait
3  |     func(val);
   |          --- value moved here
4  |     val.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(val: 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(val);
   |          --- you could clone this value
...
11 | struct MyType(i32);
   | ^^^^^^^^^^^^^ consider implementing `Clone` for this type

パターン B1

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

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

サンプル


fn main() {
    let val = MyType(Sub(42));
    func(val.0);
    val.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: `val`
 --> src\main.rs:4:5
  |
3 |     func(val.0);
  |          ----- value partially moved here
4 |     val.show_sub();
  |     ^^^ value used here after partial move
  |
  = note: partial move occurs because `val.0` has type `Sub`, which does not implement the `Copy` trait

パターン B2

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

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

サンプル

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


fn main() {
    let val = MyType(Sub(42));
    func(val.0);
    val.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: `val`
 --> src\main.rs:4:5
  |
3 |     func(val.0);
  |          ----- value partially moved here
4 |     val.show_sub();
  |     ^^^ value borrowed here after partial move
  |
  = note: partial move occurs because `val.0` has type `Sub`, which does not implement the `Copy` trait

解決策

以下の解決策はパターン A1 を例にしている。

解決策 1

参照による引数渡し

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


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

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

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

解決策 2

クローンによる引数渡し

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


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

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

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

解決策 3

コピーによる引数渡し

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


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

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

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