如何防止值被移动? [英] How to prevent a value from being moved?
问题描述
尝试解决机器人模拟器运动练习,但我面临着一个价值转移问题,似乎无法解决这个问题:
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 elegant solution:
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
}
我收到此错误:
enter code hereerror[E0382]: use of moved value: `self`
--> src/lib.rs:60:26
|
60 | 'A' => { self.advance(); },
| ^^^^ value moved here in previous iteration of loop
|
= note: move occurs because `self` has type `Robot`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `self`
--> src/lib.rs:61:26
|
60 | 'A' => { self.advance(); },
| ---- value moved here
61 | 'R' => { self.turn_right(); },
| ^^^^ value used here after move
|
= note: move occurs because `self` has type `Robot`, which does not implement the `Copy` trait
我想我得到了错误,因为advance()
返回了self
,但是我不明白为什么在块中使用该值时仍会移动该值.我真的必须实现Copy
还是错过了一个终生用例?
I think I get the error because advance()
returns self
, but I don't understand why the value is still moved as it's used inside a block. Do I really have to implement Copy
or am I missing a lifetime use case?
推荐答案
我想我得到了错误,因为advance()返回self?
I think I get the error because advance() returns self ?
不,因为advance
消耗 self
(您的其他方法也这样做),您会收到该错误.
No, you're getting that error because advance
consumes self
(and your other methods do, too).
您的问题的惯用解决方案几乎可以肯定是让您的方法对self
进行可变引用(&mut
),而不是对self
进行取值.例如.签名pub fn turn_right(mut self) -> Self
将变为pub fn turn_right(&mut self)
(请注意,后者不返回任何内容).您可以通过参考来操纵机器人的状态,并且instructions
函数应该可以正常工作.
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.
如果由于某种原因您希望继续让方法按值使用self
,则可以按以下方式重写instructions
:
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.)
这篇关于如何防止值被移动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!