Rust 如何防止值被移动?
我在尝试解决这个问题时很开心,但我面临着一个价值转移问题,我似乎无法想出一个优雅的解决方案:Rust 如何防止值被移动?,rust,move,lifetime,Rust,Move,Lifetime,我在尝试解决这个问题时很开心,但我面临着一个价值转移问题,我似乎无法想出一个优雅的解决方案: 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 {
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
}
我得到这个错误:
在此输入代码错误[E0382]:使用移动值:`self`
-->src/lib.rs:60:26
|
60 |'A'=>{self.advance();},
|^^^^值在循环的上一次迭代中移到此处
|
=注意:发生移动是因为'self'的类型为'Robot',而该类型不实现'Copy'特性
错误[E0382]:使用移动值:`self`
-->src/lib.rs:61:26
|
60 |'A'=>{self.advance();},
|----值移到了这里
61 |'R'=>{self.turn_right();},
|^^^^^移动后此处使用的值
|
=注意:发生移动是因为'self'的类型为'Robot',而该类型不实现'Copy'特性
我想我得到这个错误是因为advance()
返回self
,但我不明白为什么值在块中使用时仍然被移动。我真的必须实现Copy
吗?还是我错过了一个终生的用例
我想我得到这个错误是因为advance()返回self
不,您得到该错误是因为advance
消耗self
(您的其他方法也一样)
解决问题的惯用方法几乎肯定是让您的方法对self
进行可变引用(&mut
),而不是按值对self
进行引用。例如,签名pub-fn-turn\u right(mut-self)->self
将变成pub-fn-turn\u right(&mut-self)
(请注意,后者不会返回任何内容)。您可以通过参考操纵机器人的状态,您的指令
功能应该可以正常工作
如果出于某种原因,您希望继续让方法按值取self
,您可以按如下方式重写说明
:
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
}
也就是说,继续按值传递机器人的状态,但确保新状态在每次循环迭代时绑定到一个变量。
(我没有试着编译这段代码,但原则应该是合理的。)看看其他用户的答案,您实际上可以使用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")
}
})
}
它似乎一直在把机器人移回范围。你能借用一下吗?另外,为什么不实现
Copy
?不要实现Copy
,但要了解@EliSadoff,我实际上在努力学习如何编写好代码。我认为在这里复制是不好的,因为它会占用不必要的资源。@wimh:代码结构与我试图构建的代码结构相似,但我没有从中找到答案。谢谢你的链接,顺便说一句,这个页面似乎充满了伟大的东西。谢谢你,你的第二个解决方案确实奏效了。我确实尝试使用引用,但我遇到了同样的问题,因为测试套件使用链接调用。如果我能很好地理解,例如,从advance返回的self
正在移动值,但它从未被移回fn指令
上下文?看看其他exercism用户,您实际上可以使用fold:instructions.chars().fold(self,| robot,c{match c{'L'=>robot.turn_left(),'R'=>robot.turn_right(),'A'=>robot.advance(),=>panic!(“意外字符”)})@stamm是的,这正是问题所在。一旦你将一个值逐个传递给一个方法,你就不能再使用它了。但是由于你的方法返回的是已更改的状态,如果你将返回值赋给一个变量,你可以继续使用它。