我只是在学习Rust。我正在尝试为我的Game结构创建一个构建器结构。这是代码:
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
。
还有我所知道的复制特征,也许应该解决问题。但是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`
答案 0 :(得分:7)
鉴于您的方法签名是如何制定的,您似乎的目标是链接:
let game = GameBuilder::new().with_dimensions(...)
.with_title(...)
.build();
在Rust中,这要求GameBuilder
按值传递:
pub fn with_dimensions(self, ...) -> GameBuilder {
// ...
}
为了能够在方法中变异self
,您需要将其mut
:
pub fn with_dimensions(mut self, ...) -> GameBuilder {
}
如果您更改with_dimensions
,with_title
,game_keys
和build
的签名,则按值self
进行mut self
意图),然后链接应该工作。