我有一个名为Token
的枚举(您能猜出我想要构建的内容吗?:P)
看起来非常像这样:
enum Token {
Paren(String),
Number(String),
Name(String),
}
现在,我有一个带有以下签名的函数:
fn tokenizer(input: String) -> Vec<Token>
我没有理由相信它基本上不起作用,所以我显然有Vec<Token>
。
现在,在我的主要功能中,我有这个:
let tokens = tokenizer("(add 44 5)".to_owned());
我想做之类的以下内容:
let mut iter = tokens.iter();
while let Some(token) = iter.next() {
match token {
Token::Paren(p) => println!("Token::Paren({})", p),
Token::Number(p) => println!("Token::Number({})", p),
Token::Name(p) => println!("Token::Name({})", p),
}
}
但很明显,借用检查员并不容易让我下车。
这样做的正确方法是什么?显然,正如你可以希望通过这个项目的性质来判断,我只是想学习Rust,所以任何建议都会有所帮助,即使它与问题没有直接关系。 =)
答案 0 :(得分:3)
你的枚举拥有传入的字符串,因此解构它们将尝试按值捕获它们(并将其移出枚举)。
您可以在解构时使用ref p
来修复此问题,以便通过引用捕获..停止移动。
match *token {
Token::Paren(ref p) => println!("Token::Paren({})", p),
Token::Number(ref p) => println!("Token::Number({})", p),
Token::Name(ref p) => println!("Token::Name({})", p),
}
请注意,您还需要取消引用令牌,因为您正在使用iter()
来返回向量中对令牌的引用。如果您使用了into_iter()
,则会将所有权转移出去,您可以匹配非参考文件。但是,当您的值被移动时,您的tokens
变量现已中断。