如何防止值被移动? [英] How to prevent a value from being moved?

查看:135
本文介绍了如何防止值被移动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试解决机器人模拟器运动练习,但我面临着一个价值转移问题,似乎无法解决这个问题:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆