【发布时间】:2020-03-03 12:28:09
【问题描述】:
我正在实现一个解析器组合库:
#[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);
}
我收到了错误
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
我不知道为什么会这样。我尝试将 Copy 特征添加到 Parser 枚举,但这会导致其他错误。为什么我不能循环调用parser.run(),甚至不能调用两次?一次调用即可完美编译并运行。
使用结构体代替枚举会更好吗?
【问题讨论】:
-
你为什么选择
self而不是&self?见When would an implementation want to take ownership of self in Rust? -
看来How to prevent a value from being moved? 的答案可能会回答您的问题。如果没有,请edit您的问题来解释差异。否则,我们可以将此问题标记为已回答。
-
你好@Shepmaster,我真的不知道为什么我没有使用 &self,因为我认为我不想更改解析器对象上的任何内容。当我使用 &self 时,我面临着其他我无法理解的问题。
-
对于在学习其他编程语言后学习 Rust 的任何人:Rust 中的分配 (
=) 完全是另一种野兽。它将对象生命周期的责任与对象一起转移,使您以前为它拥有的名称已过时且无法使用。
标签: rust