我正在学习Rust,尝试为我的Game结构创建一个builder struct。以下是代码:
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,
}
}
}
但是在最后一行 input: self.input
,这段代码会出现以下错误:
error: cannot move out of borrowed content
我想我明白为什么了。由于在函数中传递的参数是 &self
,所以我不能取得它的所有权,这也是最后一行代码所做的。
我认为将 &self
改为 self
可能会起作用,但编译器会报错表示我不能修改 self
。
据我所知还有 Copy trait,也许可以解决这个问题。但是 Input 基本上是一个 HashMap,这意味着如果哈希值本身太大,复制可能很昂贵。
有什么好的方法可以解决这个问题吗?
编辑:
我尝试过这样做:
#[derive(Debug, Copy, Clone)]
struct Input {
keys_pressed: HashMap<VirtualKeyCode, bool>,
}
但是编译器报错了:
error: the trait `Copy` may not be implemented for this type; field `keys_pressed` does not implement `Copy`
with_title().build()
,因此build
接收&mut self
并且不能拥有它... 因此实际上需要修改整个方法集以在每次传递所有权时启用链接。 - Matthieu M.