为了学习生锈,我尝试过一个简单的游戏。我遇到的问题是我一直在使用部分移动的值时遇到错误,我不知道它为什么会发生。
完整的错误是:
test.rs:74:58: 74:63 error: use of partially moved value: `state`
test.rs:74 let b = state.map[1][1].feature.unwrap().interact(&mut state.player);
^~~~~
test.rs:74:11: 74:34 note: `state.map[..][..].feature` moved here because it has type `std::option::Option<~Feature<no-bounds>>`, which is non-copyable (perhaps you meant to use clone()?)
test.rs:74 let b = state.map[1][1].feature.unwrap().interact(&mut state.player);
^~~~~~~~~~~~~~~~~~~~~~~
test.rs:75:14: 75:19 error: use of partially moved value: `state`
test.rs:75 assert_eq!(state.player.health, 100);
^~~~~
<std macros>:1:1: 14:2 note: in expansion of assert_eq!
test.rs:75:3: 75:40 note: expansion site
test.rs:74:11: 74:34 note: `state.map[..][..].feature` moved here because it has type `std::option::Option<~Feature<no-bounds>>`, which is non-copyable (perhaps you meant to use clone()?)
test.rs:74 let b = state.map[1][1].feature.unwrap().interact(&mut state.player);
^~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 2 previous errors
这是从游戏中挑选出来的最低限度的工作示例:
trait Feature {
fn interact(&self, &mut Player) -> bool;
}
#[deriving(Eq, Show)]
struct Fountain {
name: &'static str
}
impl Fountain {
fn new() -> ~Feature {
~Fountain{name: "Fountain of health"} as ~Feature
}
}
impl Feature for Fountain {
fn interact(&self, player: &mut Player) -> bool {
if player.health < player.max_health {
player.health = player.max_health;
println!("You feel your wounds closing.");
}
false
}
}
struct Tile {
feature: Option<~Feature>
}
impl Tile {
fn new(feature: Option<~Feature>) -> Tile {
Tile{feature: feature}
}
}
struct Player {
health: int,
max_health: int,
}
impl Player {
fn new() -> Player {
Player{max_health: 100, health: 100}
}
}
struct GameState {
map: [[Tile, ..2], ..2],
player: Player,
}
impl GameState {
fn new() -> GameState {
GameState{
player: Player::new(),
map: [
[
Tile::new(None),
Tile::new(None)
],
[
Tile::new(None),
Tile::new(Some(Fountain::new()))
]
]
}
}
}
#[test]
fn test_fountain_interact_50() {
let mut state = GameState::new();
state.player.health = 50;
let b = state.map[1][1].feature.unwrap().interact(&mut state.player);
assert_eq!(state.player.health, 100);
assert!(!b);
}
答案 0 :(得分:2)
这是因为您在功能上调用了unwrap
:
let b = state.map[1][1].feature.unwrap().interact(&mut state.player);
unwrap
的签名是:
fn unwrap(self) -> T
这意味着您正在将值移出Option
(但您不希望如此),您想要的是参考并调用interact
:
let b = state.map[1][1].feature.get_ref().interact(&mut state.player);