Cannot Exit Borrowed Content and Builder Template

I'm just learning Rust. I am trying to create a building structure for my Game structure. Here is the code:

struct Input { keys_pressed: HashMap<VirtualKeyCode, bool>, } pub struct GameBuilder { settings: GameSettings, input: Input, } impl GameBuilder { pub fn new() -> GameBuilder { GameBuilder { settings: GameSettings { window_dimensions: (800, 600), title: "".to_string(), }, input: Input { keys_pressed: HashMap::new(), } } } pub fn with_dimensions(&mut self, width: u32, height: u32) -> &mut GameBuilder { self.settings.window_dimensions = (width, height); self } pub fn with_title(&mut self, title: &str) -> &mut GameBuilder { self.settings.title = title.to_string(); self } pub fn game_keys(&mut self, keys: Vec<VirtualKeyCode>) -> &mut GameBuilder { for key in keys { self.input.keys_pressed.insert(key, false); } self } pub fn build(&self) -> Game { let (width, height) = self.settings.window_dimensions; Game { display: glutin::WindowBuilder::new() .with_dimensions(width, height) .with_title(self.settings.title.to_string()) .build_glium() .ok() .expect("Error in WindowBuilder"), state: GameState::Running, input: self.input, } } } 

But this code complains in the last line of input: self.input as follows:

 error: cannot move out of borrowed content 

I think I understand why. Since the argument passed to the function is &self , I cannot take responsibility for this and what the last line does.

I thought it might work &self to self , but then the compilation claims that I cannot mutate self .

There is also a “Copy” property from what I know, and maybe this should fix the problem. But Input is basically a HashMap, which means that a copy can be expensive if the hash itself is too large.

What would be a good way to solve this problem?

Edit:

I tried to do this:

 #[derive(Debug, Copy, Clone)] struct Input { keys_pressed: HashMap<VirtualKeyCode, bool>, } 

But the compiler complains:

 error: the trait `Copy` may not be implemented for this type; field `keys_pressed` does not implement `Copy` 
+5
source share
1 answer

Given how your method signatures are formulated, you seem to be aiming for the chain:

 let game = GameBuilder::new().with_dimensions(...) .with_title(...) .build(); 

In Rust, this requires that GameBuilder be passed by value:

 pub fn with_dimensions(self, ...) -> GameBuilder { // ... } 

And in order to be able to mutate self inside the method, you need to make it mut :

 pub fn with_dimensions(mut self, ...) -> GameBuilder { } 

If you change the signature with_dimensions , with_title , game_keys and build to take self by value ( mut self if mutation is intended), then the chain should work.

+7
source

All Articles