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 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…