当前位置:  开发笔记 > 后端 > 正文

如何防止值被移动?

如何解决《如何防止值被移动?》经验,为你挑选了1个好方法。

我在尝试解决机器人模拟器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还是遗漏了整个生命周期的用例?



1> fjh..:

我认为我收到错误是因为advance()返回self?

不,您因为要advance 消耗 self而收到该错误(其他方法也是如此)。

解决问题的惯用方法几乎可以肯定是让您的方法采用可变的引用(&mutself而不是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
}

即继续按值传递机器人的状态,但请确保在每次循环迭代时将新状态绑定到变量。(我没有尝试编译此代码,但是原理应该是合理的。)

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有