我在尝试解决机器人模拟器Exercism练习时玩得很开心,但是我遇到了一个价值转移问题,但我似乎无法解决这个问题:
impl Robot { pub fn new(x: isize, y: isize, d: Direction) -> Self { Robot { position: Coordinate { x: x, y: y }, direction: d } } pub fn turn_right(mut self) -> Self { match self.direction { // ... }; self } pub fn turn_left(mut self) -> Self { match self.direction { // ... }; self } pub fn advance(mut self) -> Self { match self.direction { // ... }; self } pub fn instructions(self, instructions: &str) -> Self { for instruction in instructions.chars() { match instruction { 'A' => { self.advance(); }, 'R' => { self.turn_right(); }, 'L' => { self.turn_left(); }, _ => { println!("{} is not a valid instruction", instruction); }, }; } self }
我收到此错误:
impl Robot { pub fn new(x: isize, y: isize, d: Direction) -> Self { Robot { position: Coordinate { x: x, y: y }, direction: d } } pub fn turn_right(mut self) -> Self { match self.direction { // ... }; self } pub fn turn_left(mut self) -> Self { match self.direction { // ... }; self } pub fn advance(mut self) -> Self { match self.direction { // ... }; self } pub fn instructions(self, instructions: &str) -> Self { for instruction in instructions.chars() { match instruction { 'A' => { self.advance(); }, 'R' => { self.turn_right(); }, 'L' => { self.turn_left(); }, _ => { println!("{} is not a valid instruction", instruction); }, }; } self }
我认为我因为advance()
返回self
而得到了错误,但是我不明白为什么值在块内使用时仍会移动。我是否真的必须实施Copy
还是遗漏了整个生命周期的用例?
我认为我收到错误是因为advance()返回self?
不,您因为要advance
消耗 self
而收到该错误(其他方法也是如此)。
解决问题的惯用方法几乎可以肯定是让您的方法采用可变的引用(&mut
)self
而不是self
按值进行。例如,签名pub fn turn_right(mut self) -> Self
将变为pub fn turn_right(&mut self)
(请注意,后者不返回任何内容)。您可以通过参考来操纵机器人的状态,并且您的instructions
功能应该可以正常工作。
如果由于某种原因您想继续让方法self
按值使用,则可以instructions
按以下方式重写:
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 }
即继续按值传递机器人的状态,但请确保在每次循环迭代时将新状态绑定到变量。(我没有尝试编译此代码,但是原理应该是合理的。)