奇怪的错误:使用部分移动的值

时间:2014-04-23 13:41:04

标签: rust

为了学习生锈,我尝试过一个简单的游戏。我遇到的问题是我一直在使用部分移动的值时遇到错误,我不知道它为什么会发生。

完整的错误是:

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);
}

1 个答案:

答案 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);