Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
224 views
in Technique[技术] by (71.8m points)

Rust tells ''value moved here, in previous iteration of loop"

I'm implementing a parser combinator library:

#[derive(Debug)]
enum Parser {
    Char(char),
    Positive(Box<Parser>),
}

impl Parser {
    fn run(self, s: &str) -> (bool, &str) {
        match self {
            Parser::Char(ch) => {
                if s[0..1].chars().next().unwrap() == ch {
                    (true, &s[1..])
                } else {
                    (false, s)
                }
            }

            Parser::Positive(parser) => {
                //println!("{:?}", parser);
                let mut s = s;
                let mut res = (false, s);
                let parser = *parser;

                loop {
                    let ret = parser.run(s);
                    if !ret.0 {
                        break;
                    }

                    res = ret;
                    s = res.1
                }

                res
            }
            _ => (false, s),
        }
    }
}

pub fn run() {
    let x = Parser::Positive(Box::new(Parser::Char('a')));
    let ret = x.run("aaa");

    println!("{} {}", ret.0, ret.1);
}

I'm getting the error

error[E0382]: use of moved value: `parser`
  --> src/lib.rs:25:31
   |
22 |                 let parser = *parser;
   |                     ------ move occurs because `parser` has type `Parser`, which does not implement the `Copy` trait
...
25 |                     let ret = parser.run(s);
   |                               ^^^^^^ value moved here, in previous iteration of loop

I have no idea why this happens. I've tried to add the Copy trait to the Parser enum, but this causes other errors. Why can't I call parser.run() in a loop, or even twice? A single call compiles and runs perfectly.

Would it be better to use a struct instead of an enum?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

OK, changed the function's signature to

fn run<'a>(&self, s: &'a str) -> (bool, &'a str)

now and needed some other lines to be fixed.

Works now, but I don't know why.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...