【发布时间】:2015-08-06 14:58:12
【问题描述】:
我只是在学习 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。
据我所知,还有 Copy 特征,这也许应该可以解决问题。但 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`
【问题讨论】:
-
Copytrait 只能用于可简单复制的类型,这不需要任何内部堆分配内存。 -
看来我不能为 Input 做到这一点,因为 HashMap 没有实现
Copy -
@ker:老实说,如果 OP 将代码包含在链式调用中,那就更明显了!
-
MCVE 让世界变得如此简单......
-
@lhahn: MCVE;但请放心,我们都知道设法充分减少代码并仍然出现问题并不总是显而易见的。
标签: rust borrow-checker