-1

I have a struct for a Player with a method. I create a new player and try calling the method:

#[derive(Debug, Default, Clone)]
pub struct Player(pub Vec<i32>, i32, String);

impl Player {
    /// Create the player
    pub fn new_player() -> Self {
        Player(Vec::new(), 0, String::new())
    }
}

impl Player {
    pub fn add_to_hand(mut self, card: i32) -> Self {
        //push to hand
        self.0.push(card);
        self
    }
}

fn main() {
    let mut player = Player::new_player();

    while (get_total(&player.0) <= 21) && (hit == 'y') {
        println!("Want another card? y/n");
        hit = read!();
        player.add_to_hand(deck.draw());
        player.show_hand();
    }
}

I get this:

error[E0382]: borrow of moved value: `player`
let mut player = Player::new_player();
   |         ---------- move occurs because `player` has type `high_low::player::Player`, which does not implement the `Copy` trait
...
60 |         while(get_total(&player.0) <= 21) && (hit == 'y') {
   |                         ^^^^^^^^^ value borrowed here after move
...
63 |             player.add_to_hand(deck.draw());
   |             ------ value moved here, in previous iteration of loop

This is just one example, I call functions many times throughout the program, and thus get this same error every time.

I know it's because the struct Player doesn't derive the Copy trait, but I can't do that because of String and Vec<i32>. Is there a fix for this?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
user122831
  • 21
  • 1
  • 5
  • Please include `add_to_hand`'s implementation, since that is an important part of this error. It sounds like it takes `self` instead of `&self` or `&mut self`, which is the core of the problem. – loganfsmyth Mar 10 '20 at 02:24
  • @loganfsmyth Ok, added it. So replacing `mut self` with `&mut self` would fix the problem? – user122831 Mar 10 '20 at 02:35
  • It's hard to answer your question because it doesn't include a [MRE]. We can't tell what crates (and their versions), types, traits, fields, etc. are present in the code. It would make it easier for us to help you if you try to reproduce your error on the [Rust Playground](https://play.rust-lang.org) if possible, otherwise in a brand new Cargo project, then [edit] your question to include the additional info. There are [Rust-specific MRE tips](//stackoverflow.com/tags/rust/info) you can use to reduce your original code for posting here. Thanks! – Shepmaster Mar 10 '20 at 13:03

1 Answers1

2

Since add_to_hand takes ownership of the Player, because it uses mut self, not &mut self, you'd either need to:

Leave add_to_hand and use its return value, e.g.

player = player.add_to_hand(deck.draw());

but that's pretty weird since there is no reason to mutate and then return the player, so instead you should do

pub fn add_to_hand(&mut self, card: i32) {
    //push to hand
    self.0.push(card);
}

and your code should work as-is.

loganfsmyth
  • 156,129
  • 30
  • 331
  • 251