I\'m having a lot of fun trying to solve the robot simulator Exercism exercise, but I\'m facing a value moving problem for which I don\'t seem to be able to come up with an
I think I get the error because advance() returns self ?
No, you're getting that error because advance
consumes self
(and your other methods do, too).
The idiomatic solution to your problem is almost certainly to have your methods take a mutable reference (&mut
) to self
instead of taking self
by value. E.g. the signature pub fn turn_right(mut self) -> Self
would become pub fn turn_right(&mut self)
(note that the latter does not return anything). You can manipulate the robot's state through the reference, and your instructions
function should work fine.
If for some reason you want to continue to have the methods take self
by value, you could rewrite instructions
as follows:
pub fn instructions(self, instructions: &str) -> Self {
let mut robot = self;
for instruction in instructions.chars() {
robot = match instruction {
'A' => { robot.advance() },
'R' => { robot.turn_right() },
'L' => { robot.turn_left() },
_ => {
println!("{} is not a valid instruction", instruction);
robot
},
};
}
robot
}
I.e. continue passing the robot's state by value, but make sure that the new state is bound to a variable at every loop iteration. (I've not tried to compile this code, but the principle should be sound.)
Looking at the other users answers, you can actually do it with fold :
pub fn instructions(self, instructions: &str) -> Self {
instructions.chars().fold(self, |robot, c| {
match c {
'L' => robot.turn_left(),
'R' => robot.turn_right(),
'A' => robot.advance(),
_ => panic!("unexpected char")
}
})
}
It seems to keep moving back robot into the scope.